﻿#define ARTNET_SUPPORTED
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.IO.Pipes;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json;
using BasePlatformCommon;
using BasePlatformNet;
using BasePlatformNetAgent;
using L9SubSet;
using BasePlatformCommon.devChain;
using BasePlatformCom;

namespace BasePlatformAgent
{
	public class AgentCore
	{
		private BaseCoreNet baseCoreNet = null;								// 内核单例引用 - 网口
		private BaseCoreCom baseCoreCom = null;								// 内核单例引用 - 串口
		private ActivePath activePath = ActivePath.None;					// 当前活跃的数据通路

		private bool typeLogEnable = true;									// 日志全局使能
		private bool normalLogEnable = false;								// 固定日志使能
		private bool testLogEnable = false;									// 测试日志使能
		private bool detectNetLogEnable = false;							// 检测日志使能 - 网口
		private bool detectComLogEnable = false;							// 检测日志使能 - 串口
        private bool rdmTestEnable = false;                                 // rdm测试数据使能
        private bool debugLogEnable = false;                                // 调试日志使能

		private string basePipeName = @"\\.\pipe\basePipe";					// 基本管道（用于接受注册和取消注册）
		
		private string ibluePipeName = @"\\.\pipe\ibluePipe";				// iBluePlayer 消息管道
		private string ibluePipeName_Loop = @"\\.\pipe\ibluePipeLoop";		// iBluePlayer 轮询消息

		private string ledDebugPipeName = @"\\.\pipe\ledDebugPipe";			// LedDebug 消息管道

		private string baseJsonPipeName = @"\\.\pipe\basePipeJson";			// Json 消息管道
		private string baseJsonPipeNameLoop = @"\\.\pipe\basePipeJsonLoop";	// Json 轮询消息

		private bool iBluePipeResisted = false;								// iBluePlayer 注册标记
		private bool iBluePipeReceiveThreadSaveExited = false;				// iBluePlayer 管道消息接收线程安全退出标记

		private bool ledDebugPipeResisted = false;							// LedDebug 注册标记
		private bool ledDebugPipeReceiveThreadSaveExited = false;			// LedDebug 管道消息接收线程安全退出标记

		private bool willCloseByCmd = false;								// 接上层应用通知，即将关闭 BasePlatformAgent

		private string config2012Ini = "";									// 配置文件 Config2012.ini 路径
		private string agentIni = "";										// 配置文件 Agent.ini 路径
        private string defaultL9Sub = "";									// 配置文件 defaultL9.sub 路径
        private string artDevChainIni = "";									// 配置文件 ArtDevChain.ini 路径

		private string splitLine = "------------------------------------------------";

		private ShareMessage changeAreaMsgJustStart = null;					// 刚启动时接收的命令 - 更改截屏位置及大小
		private bool startSendRequestJustStart = false;						// 刚启动时接收的命令 - 开始下发显示数据

		private int xJustStart = 0;
		private int yJustStart = 0;
		private int wJustStart = 0;
		private int hJustStart = 0;
		private int fJustStart = 0;

		private Thread getDetectResultThread = null;						// 拉取后台在线检测结果线程
		private int getDetectResultPeriod_ms = 1000;						// 拉取后台在线检测结果线程执行周期

		private Form_MainSet mainSet = null;								// 系统配置面板
		private bool hardConfigFormHasShown = false;						// 系统配置面板是否已显示
		private bool showTestTabEnable = false;								// 系统配置面板中是否显示【测试】Tab页
        private bool showMainTabEnable = false;                             // 系统配置面板中是否显示【主控】Tab页

		private bool iBluePlayerIsPlaying = false;							// iBluePlayer播放标记

		private string fatalMessage = "";									// 重大错误信息（底层 winpcap 不可用）

		private string section = "AgentCore";								// 多语言文件配置节名称

		private string tip = "提示";										// MessageBox 题头

        private bool isBaseArtDevChainExist = false;                        // 存在Art设备链基准信息

        private bool isQueryArtDevChainDone = true;                        // 查询Art设备链完成标记
        
        private ArtDeviceChain baseArtDevChain;                             // 初始Art设备链

		/************************************************************************************************************/

		// 构造函数
		public AgentCore()
		{
			initEnvironment();

			if (!fatalMessage.Equals(""))
			{
				return;
			}
			else
			{
				// for debug Form_MainSet - 单独调试硬件设置时使用
				showHardConfigFormHandle(null);
			}
		}

		// 带参构造函数
		public AgentCore(string agrs0)
		{
			initEnvironment();

			if (!fatalMessage.Equals(""))
			{
				return;
			}
			else if (agrs0 != null && agrs0.Equals("startByPlayer"))
			{
				return;
			}
			else
			{
				// for debug Form_MainSet - 单独调试硬件设置时使用
				showHardConfigFormHandle(null);
			}
		}

		// 初始化运行环境
		private void initEnvironment()
		{
			tip = LanguageOper.ReadValue("Common", "tipStr");

			// 设置软件默认语言
			LanguageOper.LocalLanguage = LanguageEnum.CHS;
			//LanguageOper.LocalLanguage = LanguageEnum.EN;

			// 设置本地化语言
			setLanguageText();

			// 配置文件路径
			config2012Ini = getAppPath() + @"\conf\Config2012.ini";
			agentIni = getAppPath() + @"\conf\Agent.ini";
			defaultL9Sub = getAppPath() + @"\conf\defaultL9.sub";
            artDevChainIni = getAppPath() + @"\conf\artDevChain.ini";

			// 获取日志使能配置项
			string normalLogEnableStr = getConfigValue(agentIni, "normalLogEnable");
			string testLogEnableStr = getConfigValue(agentIni, "testLogEnable");
			string detectNetLogEnableStr = getConfigValue(agentIni, "detectNetLogEnable");
            string detectComLogEnableStr = getConfigValue(agentIni, "detectComLogEnable");
            string rdmTestEnableStr = getConfigValue(agentIni, "rdmTestEnable");
            var debugLogEnableStr = getConfigValue(agentIni, "debugLogEnable");
			normalLogEnable = normalLogEnableStr.Equals("true") ? true : false;
			testLogEnable = testLogEnableStr.Equals("true") ? true : false;
			detectNetLogEnable = detectNetLogEnableStr.Equals("true") ? true : false;
            detectComLogEnable = detectComLogEnableStr.Equals("true") ? true : false;
            rdmTestEnable = rdmTestEnableStr.Equals("true") ? true : false;
            debugLogEnable = debugLogEnableStr.Equals("true") ? true : false;
#if DEBUG
            debugLogEnable = true;
#endif

			// 按需创建日志目录
			if (!Directory.Exists(@".\log\"))
			{
				Directory.CreateDirectory(@".\log\");
			}

			// 打印 Agent 版本
			typeLog("BasePlatformAgent Start Time: " + DateTime.Now.ToString());
            var version = getVersion();
            typeLog(version, LogFile.Normal, LogTarget.FileOnly);

			// 初始化 Agent, 接收命名管道消息
			startAgent();

            // 单例模式 - 串口
            //baseCoreCom = BaseCoreCom.getInstance(normalLogEnable, testLogEnable, detectComLogEnable);
            //baseCoreCom.startBaseWatch();

            // 单例模式 - 网口
            List<string> ignoreMacList = getIgnoreNetworkCardMac();
            List<string> effectMacList = getEffectNetworkCardMac();
            baseCoreNet = BaseCoreNet.getInstance(normalLogEnable, testLogEnable, detectNetLogEnable, debugLogEnable, ignoreMacList, effectMacList);
            baseCoreNet.lowestGrayChangedHandle += SaveLowestGrayData;
            baseCoreNet.updateMainTreeArtNet += onUpdateMainTreeUIByArtNet;

            // 重大错误信息
            fatalMessage = baseCoreNet.getFatalMessage();
            if (!fatalMessage.Equals("")) {
                MessageBox.Show(fatalMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 处理刚启动时接收的命令 - 更改截屏位置及大小
            if (changeAreaMsgJustStart != null) {
                changeCaptureAreaHandle(changeAreaMsgJustStart);
                changeAreaMsgJustStart = null;
            }

            // 处理刚启动时接收的命令 - 开始下发显示数据
            if (startSendRequestJustStart) {
                baseCoreNet.changeCaptureSendFPS(fJustStart);
                baseCoreNet.changeCaptureLocationAndSize(xJustStart, yJustStart, wJustStart, hJustStart);
                baseCoreNet.startCaptureAndSend();
                startSendRequestJustStart = false;
            }

            // 设置内容发送方式
            baseCoreNet.setSendMode(SendMode.ActiveOnly);

            // 根据配置文件 Agent.ini 调整 Agent 状态
            initAgentStateByConfig();

            // 从 defaultL9.sub 文件中读取异形映射模式和颜色排列字符串
            readMapModeAndColorStringFromSub(defaultL9Sub);

            // 从 artDevChain.ini 文件中读取ArtNet设备链初始化信息
            readArtDeviceChainIni();

            // 开始检测设备拓扑结构链 - 全检测
            baseCoreNet.startTopologyListTest(DetectMode.AllDetect);

            // 定期从后台拉取检测结果
            getDetectResultThread = new Thread(getDetectResultProcess);
            getDetectResultThread.IsBackground = true;
            getDetectResultThread.Start();

            typeLog("[AgentCore] BasePlatformAgent Init Done!");
        }

		// 设置本地化语言
		public void setLanguageText()
		{
			if (LanguageOper.available == false)
			{
				return;
			}

			LanguageOper.SetCurrentCulture();

			tip = LanguageOper.ReadValue("Common", "tipStr");
		}

		// 按照 Agent.ini 调整 Agent 状态
		private void initAgentStateByConfig()
		{
			// 按照 Agent.ini 确定是否采用 socket 发包
			string sendBySocketStr = getConfigValue(agentIni, "sendBySocket");
			bool useSocket = false;
			if (sendBySocketStr.ToLower().Equals("true"))
			{
				useSocket = true;
			}
			baseCoreNet.setSendDataUseSocket(useSocket);

			// 按照 Agent.ini 确定 socket 发包模式
			string socketSendModeStr = getConfigValue(agentIni, "socketSendMode");
			if (socketSendModeStr.ToLower().Equals("sync"))
			{
				baseCoreNet.setSocketSendMode(SocketSendMode.Sync);
			}
			else
			{
				baseCoreNet.setSocketSendMode(SocketSendMode.Asyn);
			}

            // 按照 Agent.ini 确定网络速度配置
            var netSpeedStr = getConfigValue(agentIni, "netSpeed");
            if (netSpeedStr.ToLower().Equals("mega"))
            {
                baseCoreNet.SetNetSpeed(NetSpeed.HundredMegaByte);
            }
            else
            {
                baseCoreNet.SetNetSpeed(NetSpeed.GigaByte);
            }

			// 按照 Agent.ini 确定是否开启异形映射
			string res1 = startAddrMapByConfig();

			// 按照 Agent.ini 确定是否开启交换机
			string res2 = startUseSwitchByConfig();

			// 按照 Agent.ini 确定是否显示测试面板
			setShowTestTabEnableByConfig();

            // 按照 Agnet.ini 确定是否显示主控界面
            setShowMainTabEnableByConfig();

            // 按照 Agent.ini 确定超过阈值查询的配置
            setRequeryConditionByConfig();

            // 按照 Agent.ini 确定重新检测UID的配置
            setRequeryWaitTimeByConfig();

			// 提示错误信息
			if (res1.Equals("") && res2.Equals(""))
			{
				return;
			}
			else
			{
				StringBuilder sb = new StringBuilder();

				if (!res1.Equals(""))
				{
					sb.AppendLine(res1);
				}
				if (!res2.Equals(""))
				{
					sb.AppendLine(res2);
				}

				MessageBox.Show(sb.ToString(), tip, MessageBoxButtons.OK, MessageBoxIcon.Warning);

				return;
			}
		}

		// 按照 Agent.ini 确定是否周期发送 sub 文件
		private string startLoopSendSubByConfig()
		{
			string errorMessage = "";

			string sendSubEnable = getConfigValue(agentIni, "sendSubEnable");

			if (sendSubEnable.ToLower().Equals("true"))
			{
				string subDataName = getConfigValue(agentIni, "subDataName");

				string subDataFilePath = "";
				if (File.Exists(subDataName))
				{
					subDataFilePath = subDataName;
				}
				else
				{
					subDataFilePath = getAppPath() + Path.DirectorySeparatorChar + "conf" + Path.DirectorySeparatorChar + subDataName;
				}

				if (!File.Exists(subDataFilePath))
				{
					// 采用默认文件 config_rgb.sub
					subDataFilePath = getAppPath() + @"\conf\config_rgb.sub";
					if (File.Exists(subDataFilePath))
					{
						errorMessage = string.Format("自动下发 sub 文件：无法找到文件 {0}，系统将采用默认文件 /conf/config_rgb.sub 进行下发", subDataFilePath);
						if (LanguageOper.available == true)
						{
							errorMessage = string.Format(LanguageOper.ReadValue(section, "msgStr.0"), subDataFilePath);
						}
						MessageBox.Show(errorMessage, tip, MessageBoxButtons.OK, MessageBoxIcon.Warning);
						
						errorMessage = "";
						
						// 更新 Agent.ini - 停用
						//setConfigValue(agentIni, "sendSubEnable", "true");
						//setConfigValue(agentIni, "subDataName", "config_rgb.sub");

						baseCoreNet.setSubConfigPacketData(subDataFilePath);
						baseCoreNet.setSubConfigSendEnable(true);
					
						Console.WriteLine(splitLine);
					}
					// 无法找到指定文件, 同时无法找到默认文件
					else
					{
						errorMessage = string.Format("自动下发 sub 文件：无法找到文件 {0}，同时无法找到默认文件 /conf/config_rgb.sub，系统将停止自动下发", subDataFilePath);
						if (LanguageOper.available == true)
						{
							errorMessage = string.Format(LanguageOper.ReadValue(section, "msgStr.1"), subDataFilePath);
						}

						// 更新 Agent.ini - 停用
						//setConfigValue(agentIni, "sendSubEnable", "false");
						//setConfigValue(agentIni, "subDataName", "config_rgb.sub");
						
						baseCoreNet.setSubConfigSendEnable(false);
					
						Console.WriteLine(splitLine);
					}
				}
				else
				{
					// 更新 Agent.ini - 停用
					//setConfigValue(agentIni, "sendSubEnable", "true");
					//setConfigValue(agentIni, "subDataName", subDataFilePath);

					baseCoreNet.setSubConfigPacketData(subDataFilePath);
					baseCoreNet.setSubConfigSendEnable(true);
				
					Console.WriteLine(splitLine);
				}
			}

			return errorMessage;
		}

		// 按照 Agent.ini 确定是否开启异形映射
		private string startAddrMapByConfig()
		{
			string errorMessage = "";

			string addrMapEnable = getConfigValue(agentIni, "addrMapEnable");
			string addrMapFileType = getConfigValue(agentIni, "addrMapFileType");
			string addrMapFilePath = getConfigValue(agentIni, "addrMapFilePath");

			bool addrMapEnableBool = addrMapEnable.ToLower().Equals("true") ? true : false;

			if (!addrMapFilePath.Equals(""))
			{
				if (!File.Exists(addrMapFilePath))
				{
					errorMessage = string.Format("开启异形映射：无法找到文件 {0}", addrMapFilePath);
					if (LanguageOper.available == true)
					{
						errorMessage = string.Format(LanguageOper.ReadValue(section, "msgStr.2"), addrMapFilePath);
					}

					// 清除原有配置
					setConfigValue(agentIni, "addrMapEnable", "false");
					setConfigValue(agentIni, "addrMapFilePath", "");
					setConfigValue(agentIni, "addrMapFileType", "");

					// 保存界面 "开启异形映射" 勾选状态
					baseCoreNet.setAddrMapEnable(false);
				}
				else
				{
					if (addrMapFileType.ToLower().Equals("lwf"))
					{
						if (baseCoreNet != null)
						{
							baseCoreNet.readLwfAndBuildMapTable(addrMapFilePath, addrMapEnableBool);
						}
					}
					
					// 保存界面 "开启异形映射" 勾选状态
					baseCoreNet.setAddrMapEnable(true);

					Console.WriteLine(splitLine);
				}
			}

			return errorMessage;
		}

		// 按照 Agent.ini 确定是否开启交换机
		private string startUseSwitchByConfig()
		{
			string errorMessage = "";

			string useSwitch = getConfigValue(agentIni, "useSwitch");
			if (useSwitch.ToLower().Equals("true"))
			{
				string switchConfigFilePath = getConfigValue(agentIni, "switchConfigFilePath");

				if (!switchConfigFilePath.Equals("") && !File.Exists(switchConfigFilePath))
				{
					errorMessage = string.Format("开启多路交换机：无法找到文件 {0}", switchConfigFilePath);
					if (LanguageOper.available == true)
					{
						errorMessage = string.Format(LanguageOper.ReadValue(section, "msgStr.3"), switchConfigFilePath);
					}

					// 清除原有配置
					setConfigValue(agentIni, "useSwitch", "false");
					setConfigValue(agentIni, "switchConfigFilePath", "");
				}
				else
				{
					if (baseCoreNet != null)
					{
						baseCoreNet.readSwitchConfigFileJson(switchConfigFilePath);
						baseCoreNet.setUseSwitch(true);
						Console.WriteLine(splitLine);
					}
				}
			}

			return errorMessage;
		}

		// 按照 Agent.ini 确定是否显示测试面板
		private void setShowTestTabEnableByConfig()
		{
			string showTestTabEnableStr = getConfigValue(agentIni, "showTestTab");
			
			if (showTestTabEnableStr.ToLower().Equals("true"))
			{
				showTestTabEnable = true;
			}
			else
			{
				showTestTabEnable = false;
			}
		}

        // 按照 Agnet.ini 确定是否显示主控界面
        private void setShowMainTabEnableByConfig()
        {
            string showMainTabEnableStr = getConfigValue(agentIni, "showMainTab");

            if (showMainTabEnableStr.ToLower().Equals("true"))
            {
                showMainTabEnable = true;
            }
            else
            {
                showMainTabEnable = false;
            }
        }
        
		// 按照 Agent.ini 确定忽略的网卡列表
		private List<string> getIgnoreNetworkCardMac()
		{
			List<string> macList = new List<string>();

			try
			{
				string ignoreMacStr = getConfigValue(agentIni, "ignoreMac");

				if (ignoreMacStr.Equals(""))
				{
					return macList;
				}
				else
				{
					string[] subStrings = ignoreMacStr.Split(',');
					foreach (string mac in subStrings)
					{
						macList.Add(mac.Trim().Replace(":", "").Replace("-", "").ToUpper());
					}
					return macList;
				}
			}
			catch(Exception)
			{
				macList.Clear();
				return macList;
			}
		}

		// 按照 Agent.ini 确定有效的网卡列表
		private List<string> getEffectNetworkCardMac()
		{
			List<string> macList = new List<string>();

			try
			{
				string ignoreMacStr = getConfigValue(agentIni, "effectMac");

				if (ignoreMacStr.Equals(""))
				{
					return macList;
				}
				else
				{
					string[] subStrings = ignoreMacStr.Split(',');
					foreach (string mac in subStrings)
					{
						macList.Add(mac.Trim().Replace(":", "").Replace("-", "").ToUpper());
					}
					return macList;
				}
			}
			catch (Exception)
			{
				macList.Clear();
				return macList;
			}
		}

        // 按照 Agent.ini 确定超过阈值查询的配置
        private void setRequeryConditionByConfig() {
            var thresholdStr = getConfigValue(agentIni, "requeryThreshold");
            var delaySecStr = getConfigValue(agentIni, "requeryDelaySecond");
            var threshold = 0.5f;
            var delaySec = 300;
            if (!float.TryParse(thresholdStr, out threshold)) {
                return;
            }
            if (!int.TryParse(delaySecStr, out delaySec)) {
                return;
            }
            baseCoreNet.SetRequeryCondition(threshold, delaySec);
        }

        // 按照 Agent.ini 确定重新检测UID的配置
        private void setRequeryWaitTimeByConfig() {
            var waitTimeStr = getConfigValue(agentIni, "requeryWaitTime");
            var waitTime = 120;
            if (!int.TryParse(waitTimeStr, out waitTime)) {
                return;
            }
            baseCoreNet.SetRequeryWaitTime(waitTime);
        }

		// 初始化 BasePlatformAgent，开始接受基本消息
		public void startAgent()
		{
			// 基本消息接收线程 - 普通
			Thread receiveThread = new Thread(new ThreadStart(receiveBaseMessage));
			receiveThread.IsBackground = true;
			receiveThread.Start();

			// 基本消息接收线程 - Json
			Thread receiveThreadJson = new Thread(new ThreadStart(receiveBaseMessageJson));
			receiveThreadJson.IsBackground = true;
			receiveThreadJson.Start();

			// 基本消息接收线程 - Json Loop
			Thread receiveThreadJsonLoop = new Thread(new ThreadStart(receiveBaseMessageJsonLoop));
			receiveThreadJsonLoop.IsBackground = true;
			receiveThreadJsonLoop.Start();

			// 退出标记监控线程
			Thread watchThread = new Thread(watchCloseFlag);
			watchThread.IsBackground = true;
			watchThread.Start();

			typeLog("[AgentCore] BasePlatformAgent is Ready for Receive Pipe Message");
		}

		// 接收基本消息 - 线程方法
		public void receiveBaseMessage()
		{
			while (true)
			{
				try
				{
					IntPtr pipeHandleBase = NamedPipeNative.CreateNamedPipe(
								 basePipeName,
								 NamedPipeNative.PIPE_ACCESS_DUPLEX,
								 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
								 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
								 10240,
								 10240,
								 0,
								 IntPtr.Zero);

					uint u = NamedPipeNative.GetLastError();

					if (pipeHandleBase.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
					{
						Console.WriteLine("Create Base Pipe Error");
						return;
					}

					bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleBase, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

					if (connected)
					{
						readMessage(pipeHandleBase, false);
					}
					else
					{
						NamedPipeNative.CloseHandle(pipeHandleBase);
					}

					// 收到关闭命令
					if (willCloseByCmd)
					{
						break;
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
					continue;
				}
			}
			Console.WriteLine("Thread for Receive Base Message exited");
		}

		// 接收 Json 消息 - 线程方法
		public void receiveBaseMessageJson()
		{
			while (true)
			{
				try
				{
					IntPtr pipeHandleBase = NamedPipeNative.CreateNamedPipe(
								 baseJsonPipeName,
								 NamedPipeNative.PIPE_ACCESS_DUPLEX,
								 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
								 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
								 10240,
								 10240,
								 0,
								 IntPtr.Zero);

					uint u = NamedPipeNative.GetLastError();

					if (pipeHandleBase.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
					{
						Console.WriteLine("Create Json Pipe Error");
						return;
					}

					bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleBase, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

					if (connected)
					{
						readMessage(pipeHandleBase, true);
					}
					else
					{
						NamedPipeNative.CloseHandle(pipeHandleBase);
					}

					// 收到关闭命令
					if (willCloseByCmd)
					{
						break;
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
					continue;
				}
			}
			Console.WriteLine("Thread for Receive Json Message exited");
		}

		// 接收 Json 消息 - Loop - 线程方法
		public void receiveBaseMessageJsonLoop()
		{
			while (true)
			{
				try
				{
					IntPtr pipeHandleBase = NamedPipeNative.CreateNamedPipe(
								 baseJsonPipeNameLoop,
								 NamedPipeNative.PIPE_ACCESS_DUPLEX,
								 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
								 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
								 10240,
								 10240,
								 0,
								 IntPtr.Zero);

					uint u = NamedPipeNative.GetLastError();

					if (pipeHandleBase.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
					{
						Console.WriteLine("Create Json Loop Pipe Error");
						return;
					}

					bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleBase, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

					if (connected)
					{
						readMessage(pipeHandleBase, true);
					}
					else
					{
						NamedPipeNative.CloseHandle(pipeHandleBase);
					}

					// 收到关闭命令
					if (willCloseByCmd)
					{
						break;
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
					continue;
				}
			}
			Console.WriteLine("Thread for Receive Json Loop Message exited");
		}

		// 接收 iBlue 消息 - 线程方法
		public void receiveIBlueMessage()
		{
			iBluePipeReceiveThreadSaveExited = false;
			
			while (iBluePipeResisted)
			{
				try
				{
					IntPtr pipeHandleIBlue = NamedPipeNative.CreateNamedPipe(
								 ibluePipeName,
								 NamedPipeNative.PIPE_ACCESS_DUPLEX,
								 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
								 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
								 10240,
								 10240,
								 0,
								 IntPtr.Zero);

					uint u = NamedPipeNative.GetLastError();

					if (pipeHandleIBlue.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
					{
						Console.WriteLine("Create iBlue Pipe Error");
						return;
					}

					bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleIBlue, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

					if (connected && iBluePipeResisted)
					{
						readMessage(pipeHandleIBlue, false);
					}
					else
					{
						NamedPipeNative.CloseHandle(pipeHandleIBlue);
					}

					// 收到关闭命令
					if (willCloseByCmd)
					{
						break;
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
					continue;
				}
			}
			
			iBluePipeReceiveThreadSaveExited = true;
			
			Console.WriteLine("Thread for Receive iBlue Message exited");
		}

		// 接收 iBlue 消息 - Loop - 线程方法
		public void receiveIBlueMessage_Loop()
		{
			while (iBluePipeResisted)
			{
				IntPtr pipeHandleIBlue = NamedPipeNative.CreateNamedPipe(
							 ibluePipeName_Loop,
							 NamedPipeNative.PIPE_ACCESS_DUPLEX,
							 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
							 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
							 10240,
							 10240,
							 0,
							 IntPtr.Zero);

				uint u = NamedPipeNative.GetLastError();

				if (pipeHandleIBlue.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
				{
					Console.WriteLine("Create iBlue Loop Pipe Error");
					return;
				}

				bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleIBlue, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

				if (connected && iBluePipeResisted)
				{
					readMessage(pipeHandleIBlue, false);
				}
				else
				{
					NamedPipeNative.CloseHandle(pipeHandleIBlue);
				}

				// 收到关闭命令
				if (willCloseByCmd)
				{
					break;
				}
			}
			Console.WriteLine("Thread for Receive iBlue Loop Message exited");
		}

		// 接收 LedDebug 消息 - 线程方法
		public void receiveLedDebugMessage()
		{
			ledDebugPipeReceiveThreadSaveExited = false;

			while (ledDebugPipeResisted)
			{
				IntPtr pipeHandleLedDebug = NamedPipeNative.CreateNamedPipe(
							 ledDebugPipeName,
							 NamedPipeNative.PIPE_ACCESS_DUPLEX,
							 NamedPipeNative.PIPE_TYPE_MESSAGE | NamedPipeNative.PIPE_READMODE_MESSAGE,
							 NamedPipeNative.PIPE_UNLIMITED_INSTANCES,
							 10240,
							 10240,
							 0,
							 IntPtr.Zero);

				uint u = NamedPipeNative.GetLastError();

				if (pipeHandleLedDebug.ToInt32() == NamedPipeNative.INVALID_HANDLE_VALUE)
				{
					Console.WriteLine("Create LedDebug Pipe Error");
					return;
				}

				bool connected = NamedPipeNative.ConnectNamedPipe(pipeHandleLedDebug, null) ? true : (NamedPipeNative.GetLastError() == NamedPipeNative.ERROR_PIPE_CONNECTED);

				if (connected && ledDebugPipeResisted)
				{
					readMessage(pipeHandleLedDebug, true);
				}
				else
				{
					NamedPipeNative.CloseHandle(pipeHandleLedDebug);
				}

				// 收到关闭命令
				if (willCloseByCmd)
				{
					break;
				}
			}

			ledDebugPipeReceiveThreadSaveExited = true;

			Console.WriteLine("Thread for Receive LedDebug Message exited");
		}

		// 读取并处理消息 - 共用
		public void readMessage(object arg, bool useJson)
		{
			IntPtr pipeHandle = (IntPtr)arg;

			byte[] numReadWritten = new byte[4];
			byte[] intBytes = new byte[4];

			// 获取消息长度
			NamedPipeNative.ReadFile(pipeHandle, intBytes, 4, numReadWritten, 0);
			int len = BitConverter.ToInt32(intBytes, 0);

			// 获取消息数据
			byte[] recBuffer = new byte[len];
			NamedPipeNative.ReadFile(pipeHandle, recBuffer, (uint)len, numReadWritten, 0);

			// 解析消息内容
			ShareMessage msg = null;
			ShareMessage response = null;
			if (useJson == false)
			{
				msg = BytesConvert.BytesToObject<ShareMessage>(recBuffer);
			}
			else
			{
				msg = JsonConvert.DeserializeObject<ShareMessage>(System.Text.Encoding.UTF8.GetString(recBuffer));
			}

			// 处理基本消息: 注册管道/取消注册管道
			if (msg.Type.Equals(MessageType.BaseMessage))
			{
				try
				{
					response = handleBaseMessage(msg);
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
				}
			}
			// 处理 IBlue 消息
			else if (msg.Type.Equals(MessageType.IBlueMessage))
			{
				try
				{
					response = handleIBlueMessage(msg);
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
				}
			}
			// 处理 LedDebug 消息
			else if (msg.Type.Equals(MessageType.LedDebugMessage))
			{
				try
				{
					response = handleLedDebugMessage(msg);
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
				}
			}

			// 发送反馈消息
			if (response != null)
			{
				byte[] responseBuffer = null;
				if (useJson == false)
				{
					responseBuffer = BytesConvert.ObjectToBytes<ShareMessage>(response);
				}
				else
				{
					responseBuffer = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(response));
				}
				len = responseBuffer.Length;
				numReadWritten = new byte[4];
				NamedPipeNative.WriteFile(pipeHandle, BitConverter.GetBytes(len), 4, numReadWritten, 0);
				NamedPipeNative.WriteFile(pipeHandle, responseBuffer, (uint)len, numReadWritten, 0);
			}

			// 关闭管道
			NamedPipeNative.FlushFileBuffers(pipeHandle);
			NamedPipeNative.DisconnectNamedPipe(pipeHandle);
			NamedPipeNative.CloseHandle(pipeHandle);

			msg = null;
		}

		// 处理基本消息: 注册管道/取消注册管道 - TODO:返回底层 WinPcap 的安装状态
		public ShareMessage handleBaseMessage(ShareMessage baseMsg)
		{
			// 注册 iBlue 管道
			if (baseMsg.Value.Equals(MessageValue.Base_Regist) && baseMsg.Parameters[0].ToLower().Equals("iblue"))
			{
				if (iBluePipeResisted == false)
				{
					iBluePipeResisted = true;

					// 启动 iBlue 消息接收线程
					Thread th = new Thread(new ThreadStart(receiveIBlueMessage));
					th.IsBackground = true;
					th.Start();

					// 启动 iBlue Loop 消息接收线程
					Thread th_loop = new Thread(new ThreadStart(receiveIBlueMessage_Loop));
					th_loop.IsBackground = true;
					th_loop.Start();

					baseMsg.Value = "success";
					baseMsg.Handled = true;

					Console.WriteLine("Regist iBlue Pipe Success");
				}
				else
				{
					iBluePipeResisted = false;
					int waitNum = 0;
					while (iBluePipeReceiveThreadSaveExited == false)
					{
						Thread.Sleep(50);
						waitNum++;
						if (waitNum > 20)
						{
							Console.WriteLine("break!");
							break;
						}
					}
					if (iBluePipeResisted == false)
					{
						baseMsg.Value = "iBlue Pipe has already Resisted.";
						baseMsg.Handled = false;
						
						Console.WriteLine("iBlue Pipe has already Resisted");
					}
					else
					{
						iBluePipeResisted = true;

						// 启动 iBlue 消息接收线程
						Thread th = new Thread(new ThreadStart(receiveIBlueMessage));
						th.IsBackground = true;
						th.Start();

						// 启动 iBlue Loop 消息接收线程
						Thread th_loop = new Thread(new ThreadStart(receiveIBlueMessage_Loop));
						th_loop.IsBackground = true;
						th_loop.Start();

						baseMsg.Value = "success";
						baseMsg.Handled = true;

						Console.WriteLine("Force Regist iBlue Pipe Success");
					}
				}
			}
			// 取消注册 iBlue 管道
			else if (baseMsg.Value.Equals(MessageValue.Base_UnRegist) && baseMsg.Parameters[0].ToLower().Equals("iblue"))
			{
				baseCoreNet.stopCaptureAndSend();

				iBluePipeResisted = false;

				baseMsg.Value = "success";
				baseMsg.Handled = true;

				Console.WriteLine("UnRegist iBlue Pipe Success");
			}
			// 注册 LedDebug 管道
			else if (baseMsg.Value.Equals(MessageValue.Base_Regist) && baseMsg.Parameters[0].ToLower().Equals("leddebug"))
			{
				if (ledDebugPipeResisted == false)
				{
					ledDebugPipeResisted = true;
					Thread th = new Thread(new ThreadStart(receiveLedDebugMessage));
					th.IsBackground = true;
					th.Start();

					baseMsg.Value = "success";
					baseMsg.Handled = true;

					Console.WriteLine("Regist LedDebug Pipe Success");
				}
				else
				{
					ledDebugPipeResisted = false;
					int waitNum = 0;
					while (ledDebugPipeReceiveThreadSaveExited == false)
					{
						Thread.Sleep(50);
						waitNum++;
						if (waitNum > 20)
							break;
					}
					if (ledDebugPipeResisted == false)
					{
						baseMsg.Value = "LedDebug Pipe has already Resisted.";
						baseMsg.Handled = false;
						
						Console.WriteLine("LedDebug Pipe has already Resisted");
					}
					else
					{
						ledDebugPipeResisted = true;
						Thread th = new Thread(new ThreadStart(receiveLedDebugMessage));
						th.IsBackground = true;
						th.Start();

						baseMsg.Value = "success";
						baseMsg.Handled = true;

						Console.WriteLine("Force Regist LedDebug Pipe Success");
					}
				}
			}
			// 取消注册 LedDebug 管道
			else if (baseMsg.Value.Equals(MessageValue.Base_UnRegist) && baseMsg.Parameters[0].ToLower().Equals("leddebug"))
			{
				ledDebugPipeResisted = false;

				try
				{
					if (baseCoreNet != null)
					{
						baseCoreNet.ledDebugSetEffectSubAndPort("0:11111111");
					}
				}
				catch (Exception ex)
				{
					Console.WriteLine(ex.Message + ex.StackTrace);
				}

				baseMsg.Value = "success";
				baseMsg.Handled = true;

				Console.WriteLine("UnRegist LedDebug Pipe Success");
			}

			return baseMsg;
		}

		// 处理 iBluePlayer 消息 - 入口
		public ShareMessage handleIBlueMessage(ShareMessage iblueMsg)
		{
            switch (iblueMsg.Value) {
                case MessageValue.IBlue_Test: // iBlue 通信测试
                    return iBlueTestHandle(iblueMsg);

                case MessageValue.IBlue_StartSendDispData: // 开始下发显示数据
                    return startSendDispDataHandle(iblueMsg);

                case MessageValue.IBlue_StopSendDispData: // 停止下发显示数据
                    return stopSendDispDataHandle(iblueMsg);

                case MessageValue.IBlue_PauseSendDispData: // 暂停下发显示数据
                    return pauseSendDispDataHandle(iblueMsg);

                case MessageValue.IBlue_ResumeSendDispData: // 恢复下发显示数据
                    return resumeSendDispDataHandle(iblueMsg);

                case MessageValue.IBlue_ChangeCaptureArea: // 改变截屏区域位置
                    return changeCaptureAreaHandle(iblueMsg);

                case MessageValue.IBlue_ChangeCaptureFps: // 改变截屏帧频
                    return changeCaptureFpsHandle(iblueMsg);

                case MessageValue.IBlue_SetAddrMapEnable: // 设置异形映射使能
                    return setAddrMapEnableHandle(iblueMsg);

                case MessageValue.IBlue_ReadBinDataFromLwfOrJson: // 从 lwf 布线文件中读取 bin 区
                    return readBinDataFromLwfHandle(iblueMsg);

                case MessageValue.IBlue_GetSubEquActiveState: // 查询底层硬件设备的连接状态
                    return getSubEquActiveStateHandle(iblueMsg);

                case MessageValue.IBlue_CloseAgent: // 关闭后台 BasePlatformAgent
                    return closeAgentHandle(iblueMsg);

                case MessageValue.IBlue_SetUseSwitch: // 设置是否支持交换机
                    return setUseSwitchHandle(iblueMsg);

                case MessageValue.IBlue_ReadSwitchConfigFile: // 读取多路交换机配置文件
                    return readSwitchConfigFileHandle(iblueMsg);

                case MessageValue.IBlue_ShowHardConfigForm: // 显示硬件设置界面
                    return showHardConfigFormHandle(iblueMsg);

                case MessageValue.IBlue_GetAddrMapParameter: // 查询异形映射参数
                    return getAddrMapParameterHandle(iblueMsg);

                case MessageValue.IBlue_GetAddrMapTable: // 查询异形映射表
                    return getAddrMapTableHandle(iblueMsg);

                case MessageValue.IBlue_GetAgentVersion: // 查询 Agent 版本
                    return getAgentVersionHandle(iblueMsg);

                case MessageValue.IBlue_GetDeviceChainJson: // 查询底层设备链（Json格式）
                    return getDeviceChainJsonHandle(iblueMsg);

                case MessageValue.IBlue_GetDeviceChainStatusJson: // 查询底层设备链摘要信息（Json格式）
                    return getDeviceChainStatusJsonHandle(iblueMsg);

                case MessageValue.IBlue_GetDeviceChainDetailJson: // 查询底层设备链详细信息（Json格式）
                    return getDeviceChainDetailJsonHandle(iblueMsg);

                case MessageValue.IBlue_SetPlayingState: // 设置 iBluePlayer 的播放状态
                    return setPlayingStateHandle(iblueMsg);

                case MessageValue.IBlue_GetConfigExpandState: // 查询 MainSet 底层硬件配置窗展开状态
                    return getConfigExpandStateHandle(iblueMsg);

                case MessageValue.IBlue_SetProgramBrightness: // 设置节目亮度
                    return setProgramBrightnessHandle(iblueMsg);

                case MessageValue.IBlue_GetSubConfigData: // 获取分控配置 sub 数据
                    return getSubConfigDataHandle(iblueMsg);

                case MessageValue.IBlue_SetMcuDispParameter: // 设置 MCU 显示参数
                    return setMcuDispParameterHandle(iblueMsg);

                case MessageValue.IBlue_SetUserColorType: // 设置用户颜色模式
                    return setUserColorTypeHandle(iblueMsg);

                case MessageValue.IBlue_SetAddrMapDatPlayingMask: // 设置 DatPlayForm 播放掩码
                    return setAddrMapDatPlayingMaskHandle(iblueMsg);

                case MessageValue.IBlue_SetUserLanguage: // 设置用户语言
                    return setUserLanguageHandle(iblueMsg);

                case MessageValue.IBlue_StartQueryArtDeviceChain: // 发起ArtNet设备链查询
                    return startQueryArtDeviceChainHandle(iblueMsg);

                case MessageValue.IBlue_GetBaseArtDeviceChain: // 获取ArtNet基准设备链信息
                    return getBaseArtDeviceChainHandle(iblueMsg);

                case MessageValue.IBlue_GetCurrentArtDeviceChain: // 获取ArtNet当前设备链信息
                    return getCurrentArtDeviceChainHandle(iblueMsg);

                case MessageValue.IBlue_SetCurrentArtDeviceChainToBase: // 设置ArtNet当前设备链信息设为基准
                    return setCurrentArtDeviceChainToBaseHandle(iblueMsg);

                case MessageValue.IBlue_GetErrorArtDevice: // 获取ArtNet错误信息
                    return getErrorArtDeviceHandle(iblueMsg);

                case MessageValue.IBlue_GetArtDeviceDetail: // 获取ArtNet灯具详情
                    return getArtDeviceDetailHandle(iblueMsg);

                default: // 其他未定义消息
                    Console.WriteLine("!Unknown Message " + iblueMsg.Value);
                    iblueMsg.Handled = true;
                    return iblueMsg;
            }
		}

		// 处理 ledDebug 消息 - 入口
		public ShareMessage handleLedDebugMessage(ShareMessage ledMsg)
		{
			// LedDebug 通信测试
			if (ledMsg.Value.Equals(MessageValue.LED_Test))
			{
				Console.WriteLine(JsonConvert.SerializeObject(ledMsg));
				return ledDebugTestHandle(ledMsg);
			}
			// LedDebug 获取分控数量
			else if (ledMsg.Value.Equals(MessageValue.LED_GetSubControlNum))
			{
				return ledDebugGetSubControlNumHandle(ledMsg);
			}
			// LedDebug 设置/取消设置有效的分控号、端口号
			else if (ledMsg.Value.Equals(MessageValue.LED_SetEffectSubAndPort))
			{
				return ledDebugSetEffectSubAndPortHandle(ledMsg);
			}
			// 其他未定义消息
			else
			{
				Console.WriteLine("!Unknown Message: " + ledMsg.Value);
				ledMsg.Handled = true;
				return ledMsg;
			}
		}

		// 监控 willCloseByCmd 变量, 响应整体退出逻辑
		private void watchCloseFlag()
		{
			while (true)
			{
				if (willCloseByCmd == false)
				{
					Thread.Sleep(100);
				}
				else
				{
					break;
				}
			}

			Console.WriteLine("BaseCoreNet Start Dispose");
			
			if (baseCoreNet != null)
			{
				baseCoreNet.Dispose();
			}

			Console.WriteLine("BaseCoreNet End Dispose");

			MessageBoxManager.Unregister();

			// 杀死自身进程
			try
			{
				Process.GetCurrentProcess().Kill();
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message + e.StackTrace);
			}
		}

		#region 在线检测结果回显

		private int lastDetectSubEquNum = -1;
		private int[] totalCommList = new int[260];
		private int[] errorCommList = new int[260];
		private int lostPacketNumLast = -1;

		// 周期拉取后台检测结果, 更新前台信息 - 线程方法
		private void getDetectResultProcess()
		{
			int loopNum = 0;
			bool lastUseSwitch = baseCoreNet.getUseSwitch();

			for(int i = 0; i < totalCommList.Length; i++)
			{
				totalCommList[i] = 0;
				errorCommList[i] = 0;
			}

			while (true)
			{
                //if (baseCoreNet.getDetectType() != DetectType.Normal) {
                //    Thread.Sleep(getDetectResultPeriod_ms);
                //    continue;
                //}
				if (hardConfigFormHasShown == false)
				{
					Thread.Sleep(getDetectResultPeriod_ms);
					continue;
				}
				else
				{
					loopNum++;
					if (loopNum > 1000000)
					{
						loopNum = 1;
					}

					/**********************************************************************************************************************************************/

					bool useSwitch = baseCoreNet.getUseSwitch();
					//string topoStrNet = baseCoreNet.getDeviceTopologyChain();

					// 拉取检测结果 - 网口
					List<ControlNode> controlNodeListNet = baseCoreNet.getControlNodeList();

					#region 根据检测结果输出日志 - 基于网口检测结果

					// 判断检测结果是否发生变化
					if (lastDetectSubEquNum == -1)
					{
						lastDetectSubEquNum = controlNodeListNet.Count;
					}
					else
					{
						// 检测结果发生变化
						if (lastDetectSubEquNum != controlNodeListNet.Count && baseCoreNet.detectNetLogEnable == true)
						{
							string binFileName = String.Format("[{0}-{1:00}-{2:00}] [ {3:00}-{4:00}-{5:00}.{6:000} ] [{7}].bin", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond, controlNodeListNet.Count);
							BinaryWriter binWriter = new BinaryWriter(new FileStream(getAppPath() + "/log/" + binFileName, FileMode.Create));

							byte[] binData = new byte[320 * 256];
							binData[0] = (byte)(controlNodeListNet.Count);

							string message = String.Format("SubNum Changed, last: {0,-5}current: {1,-5}", lastDetectSubEquNum, controlNodeListNet.Count);
							baseCoreNet.typeLog(message, LogFile.DetectNet, LogTarget.FileOnly);

							// 保存分控信息
							int subControlNum = 0;
							foreach (ControlNode controlNode in controlNodeListNet)
							{
								if (controlNode.type == 1)
								{
									subControlNum++;

									SubControl subControl = new SubControl(controlNode.replyData);
									subControl.index = controlNode.mySubCtrlDepth + 1;
									subControl.ProductionInfo.Version = controlNode.version;
									subControl.buildTipMessage();

									binData[subControl.index] = 0x1;
									Array.Copy(controlNode.replyData, 0, binData, subControl.index * 256, 256);

									string subIndexStr = String.Format(" {0}", controlNode.mySubCtrlDepth + 1);

									// 判断是否有等位节点
									if (controlNode.brotherCount > 0)
									{
										subIndexStr += String.Format(" [{0}]", controlNode.brotherCount + 1);
									}

									// 判断是否连续
									if (controlNode.noContinueFlag == true)
									{
										subIndexStr += " *";
									}

									string formatStr = "分控{0,-10}{1,-40}Version: {2,-15}";
									if (LanguageOper.available == true)
									{
										formatStr = LanguageOper.ReadValue(section, "formatStr.0");
									}
									message = String.Format(formatStr, subIndexStr, subControl.tipMessage, subControl.ProductionInfo.Version);
									baseCoreNet.typeLog(message, LogFile.DetectNet, LogTarget.FileOnly);
								}
							}

							//　保存附属设备信息
							foreach (ControlNode controlNode in controlNodeListNet)
							{
								if (controlNode.type == 0)
								{
									Equipment equipment = new Equipment(controlNode.replyData);
									equipment.index = controlNode.mySubCtrlDepth + controlNode.myEquipmentDepth + 1;
									equipment.ProductionInfo.Version = controlNode.version;
									equipment.buildTipMessage();

									binData[equipment.index] = 0x1;
									Array.Copy(controlNode.replyData, 0, binData, equipment.index * 256, 256);

									string equIndexStr = String.Format(" {0}", controlNode.myEquipmentDepth + 1);

									// 判断是否有等位节点
									if (controlNode.brotherCount > 0)
									{
										equIndexStr += String.Format(" [{0}]", controlNode.brotherCount + 1);
									}

									// 判断是否连续
									if (controlNode.noContinueFlag == true)
									{
										equIndexStr += " *";
									}

									string formatStr = "附属设备{0,-10}{1,-40}Version: {2,-15}";
									if (LanguageOper.available == true)
									{
										formatStr = LanguageOper.ReadValue(section, "formatStr.1");
									}
									message = String.Format(formatStr, equIndexStr, equipment.tipMessage, equipment.ProductionInfo.Version);
									baseCoreNet.typeLog(message, LogFile.DetectNet, LogTarget.FileOnly);
								}
							}

							baseCoreNet.typeLog(splitLine, LogFile.DetectNet, LogTarget.FileOnly);

							binWriter.Write(binData);
							binWriter.Flush();
							binWriter.Close();
						}
					}

					lastDetectSubEquNum = controlNodeListNet.Count;

					// 每 30 个周期判断是否有异常发生
					if (controlNodeListNet.Count > 0 && loopNum % 30 == 0 && baseCoreNet.detectNetLogEnable == true)
					{
						// 丢包数 = 第一个分控总包数 - 最后一个分控总包数
						ControlNode firstNode = null;
						ControlNode lastNode = null;
						foreach (ControlNode controlNode in controlNodeListNet)
						{
							if (controlNode.type == 1)
							{
								if (firstNode == null)
								{
									firstNode = controlNode;
								}
								lastNode = controlNode;
							}
						}

						if (firstNode != null && lastNode != null)
						{
							SubControl firstSubControl = new SubControl(firstNode.replyData);
							firstSubControl.index = firstNode.mySubCtrlDepth + 1;
							firstSubControl.ProductionInfo.Version = firstNode.version;
							firstSubControl.buildTipMessage();

							SubControl lastSubControl = new SubControl(lastNode.replyData);
							lastSubControl.index = lastNode.mySubCtrlDepth + 1;
							lastSubControl.ProductionInfo.Version = lastNode.version;
							lastSubControl.buildTipMessage();

							int lostPacketNum = firstSubControl.TotalComm - lastSubControl.TotalComm;

							// 初始化数据
							if (lostPacketNumLast == -1)
							{
								lostPacketNumLast = lostPacketNum;
							}
							// 丢包数变化 > 20
							else if (lostPacketNum - lostPacketNumLast > 20)
							{
								string message = String.Format("Lost Packets too many, {0,-10}{1,-10}{2,-10}", lostPacketNum, lostPacketNumLast, lostPacketNum - lostPacketNumLast);
								baseCoreNet.typeLog(message, LogFile.DetectNet, LogTarget.FileOnly);
							}
							//else
							//{
							//	baseCoreNet.typeLog("lostPacketNum = " + lostPacketNum, LogFile.Detect, LogTarget.FileOnly);
							//}
						}

						foreach (ControlNode controlNode in controlNodeListNet)
						{
							if (controlNode.type == 1)
							{
								SubControl subControl = new SubControl(controlNode.replyData);
								subControl.index = controlNode.mySubCtrlDepth + 1;
								subControl.ProductionInfo.Version = controlNode.version;
								subControl.buildTipMessage();

								// 错包数变化 > 20
								if (subControl.ErrorComm - errorCommList[subControl.index] > 20 && errorCommList[subControl.index] > 0)
								{
									string message = String.Format("Error Packets too many, SubIndex: {0,-5}{1,-10}{2,-10}{3,-10}", subControl.index, errorCommList[subControl.index], subControl.ErrorComm, subControl.ErrorComm - errorCommList[subControl.index]);
									baseCoreNet.typeLog(message, LogFile.DetectNet, LogTarget.FileOnly);
								}

								// 更新记录信息
								totalCommList[subControl.index] = subControl.TotalComm;
								errorCommList[subControl.index] = subControl.ErrorComm;
							}
						}
					}

					#endregion

					#region 构造前台显示用的数据结构 - 基于网口检测结果

                    var mainControlNet = genDetectResultMainControlNet(useSwitch, controlNodeListNet);

					#endregion

					#region 有网口连接了设备，优先根据网口设备刷新

					// 根据 mainControlNet 是否为 null 判断网口通路是否活跃
					if (mainControlNet != null)
					{
						activePath = ActivePath.Net;
						if (mainSet != null)
						{
							mainSet.setActivePath(activePath);
						}
						updateMainTreeUI(mainControlNet, controlNodeListNet);
						Thread.Sleep(getDetectResultPeriod_ms);
						continue;
					}

					#endregion

					/**********************************************************************************************************************************************/

					// 拉取检测结果 - 串口
                    List<ControlNode> controlNodeListCom = null;
                    if (baseCoreCom != null) {
                        controlNodeListCom = baseCoreCom.getControlNodeList(); 
                    }

					#region 根据检测结果输出日志 - 基于串口检测结果
					#endregion

					#region 构造前台显示用的数据结构 - 基于串口检测结果

                    ComMainControl comMainControl = null;
                    if (baseCoreCom != null) {
                        comMainControl = baseCoreCom.getActiveComMainControl();
                    }

					MainControl mainControlCom = new MainControl(1);	// 串口主控
					MainPort mainPortCom = new MainPort();
					mainPortCom.HideFlag = false;						// 主控端口

					List<SubControlChain> subControlChainListCom = new List<SubControlChain>();

					if (comMainControl != null && !comMainControl.index.Equals(""))
					{
						try
						{
							mainControlCom.index = Convert.ToInt32(comMainControl.index);
						}
						catch (Exception)
						{
							MessageBox.Show("Error: comMainControl.index = " + comMainControl.index);
						}
						string versionStr = "版本：";
						if (LanguageOper.available == true)
						{
							versionStr = LanguageOper.ReadValue(section, "str.0");
						}
						mainControlCom.tipMessage = versionStr + comMainControl.version;
						if (comMainControl.version.Equals(""))
						{
							mainControlCom.tipMessage = "";
						}

						int mainPortType = comMainControl.getMainCtrlActivePort();
						if (mainPortType == ComMainPort.U)
						{
							mainPortCom.name = "端口 U";
							if (LanguageOper.available == true)
							{
								mainPortCom.name = LanguageOper.ReadValue(section, "str.1");
							}
						}
						else if (mainPortType == ComMainPort.D)
						{
							mainPortCom.name = "端口 D";
							if (LanguageOper.available == true)
							{
								mainPortCom.name = LanguageOper.ReadValue(section, "str.2");
							}
						}
						else
						{
							mainPortCom.name = "无分控";
							if (LanguageOper.available == true)
							{
								mainPortCom.name = LanguageOper.ReadValue(section, "str.3");
							}
						}

						SubControlChain subControlChainAllCom = new SubControlChain();
						subControlChainAllCom.HideFlag = true;	// 串口主控 - 不显示交换机端口级
						subControlChainListCom.Add(subControlChainAllCom);

						int subControlNumCom = 0;
						int equControlNumCom = 0;
						foreach (ControlNode controlNode in controlNodeListCom)
						{
							// 分控
							if (controlNode.type == 1)
							{
								SubControl subControl = new SubControl(controlNode.replyData);
								subControl.index = controlNode.mySubCtrlDepth + 1;
								if (controlNode.brotherCount > 0)
								{
									subControl.HasErrorNeedDisp = true;
									subControl.brotherCount = controlNode.brotherCount + 1;
								}
								if (controlNode.noContinueFlag == true)
								{
									subControl.HasNoContinueMarkNeedDisp = true;
								}

								subControlChainListCom[0].SubControlList.Add(subControl);

								subControlNumCom++;
							}
							// 附属设备
							else if (controlNode.type == 0)
							{
								Equipment equipment = new Equipment(controlNode.replyData);
								equipment.index = controlNode.myEquipmentDepth + 1;
								if (controlNode.brotherCount > 0)
								{
									equipment.HasErrorNeedDisp = true;
									equipment.brotherCount = controlNode.brotherCount + 1;
								}
								if (controlNode.noContinueFlag == true)
								{
									equipment.HasNoContinueMarkNeedDisp = true;
								}

								subControlChainListCom[0].EquControlList.Add(equipment);

								equControlNumCom++;
							}
						}

						if (subControlNumCom > 0 || equControlNumCom > 0)
						{
							for (int k = 0; k < subControlChainListCom.Count; k++)
							{
								subControlChainListCom[k].calcSubChainTotalInfo();
								mainPortCom.SubControlChainList.Add(subControlChainListCom[k]);
							}
						}
						else
						{
							mainPortCom.name = "无设备";
							if (LanguageOper.available == true)
							{
								mainPortCom.name = LanguageOper.ReadValue(section, "str.3");
							}
						}

						mainPortCom.calcMainPortTotalInfo();
						mainControlCom.MainPortList.Add(mainPortCom);

						while ((subControlNumCom > 0 || equControlNumCom > 0) && mainPortType == ComMainPort.Unknown)
						{
							mainPortType = comMainControl.getMainCtrlActivePort();
							if (mainPortType == ComMainPort.U)
							{
								mainPortCom.name = "端口 U";
								if (LanguageOper.available == true)
								{
									mainPortCom.name = LanguageOper.ReadValue(section, "str.1");
								}
							}
							else if (mainPortType == ComMainPort.D)
							{
								mainPortCom.name = "端口 D";
								if (LanguageOper.available == true)
								{
									mainPortCom.name = LanguageOper.ReadValue(section, "str.2");
								}
							}
							else
							{
								mainPortCom.name = "无设备";
								if (LanguageOper.available == true)
								{
									mainPortCom.name = LanguageOper.ReadValue(section, "str.3");
								}
							}
							Thread.Sleep(1);
						}
					}
					else
					{
						mainControlCom = null;
					}
					
					#endregion

					#region 有串口连接了设备，根据串口设备刷新
				
					if (mainControlCom != null)
					{
						activePath = ActivePath.Com;
						if (mainSet != null)
						{
							mainSet.setActivePath(activePath);
						}
						updateMainTreeUI(mainControlCom, controlNodeListCom);
						Thread.Sleep(getDetectResultPeriod_ms);
						continue;
					}

					#endregion

					/**********************************************************************************************************************************************/

					// 网口、串口均未接设备
					if (mainControlNet == null && mainControlCom == null)
					{
						activePath = ActivePath.None;
						if (mainSet != null)
						{
							mainSet.setActivePath(activePath);
						}
						updateMainTreeUI(null, null);
						Thread.Sleep(getDetectResultPeriod_ms);
						continue;
					}
				}
			}
		}

		// 刷新前台界面
		private void updateMainTreeUI(MainControl mainControl, List<ControlNode> controlNodeList)
		{
			if (mainSet != null)
			{
				try
				{
					// 刷新前台界面
					mainSet.Invoke(mainSet.updateMainTreeDelegate, mainControl, controlNodeList);
				}
				catch (Exception)
				{
					;
				}
			}
		}

		// 周期拉取后台检测结果，封装为 MainControl 对象，用于向 iBluePlayer 返回 Json
		private MainControl getDetectResultMainControl()
		{
			if (baseCoreNet != null)
			{
				// 获取声明的设备链信息
				List<DMainControl> declareMainControlList = baseCoreNet.getDeclareMainControlList();
				DMainControl dMainControl = new DMainControl();
				if (declareMainControlList != null && declareMainControlList.Count > 0)
				{
					// 目前只支持单主控
					dMainControl = declareMainControlList[0];
				}

				// 拉取检测结果
				List<ControlNode> controlNodeList = baseCoreNet.getControlNodeList();

				List<MacTable> subMacTable = null;
				List<string> macList = null;
				bool useSwitch = baseCoreNet.getUseSwitch();

				// 启用交换机
				if (useSwitch == true)
				{
					subMacTable = baseCoreNet.getLineMacTable("sub");
					macList = baseCoreNet.getMacList();
				}

				if (controlNodeList.Count > 0)
				{
					// 构造 Json 序列化使用的数据结构

					// 主控
					MainControl mainControl = new MainControl(0);
					mainControl.index = 0;

					/****************** 网口主控, 隐藏主控端口和分控链路级 ********************/

					// 主控端口
					MainPort mainPort = new MainPort();
					mainPort.index = 0;
					mainPort.DeclareSubControlNum = dMainControl.declareSubNum;

					// 分控链路
					if (useSwitch == true)
					{
						int subControlChainIndex = 0;
						foreach (string switchPortMac in macList)
						{
							SubControlChain subControlChain = new SubControlChain();
							subControlChain.index = subControlChainIndex;
							subControlChain.DeclareSubControlNum = dMainControl.declareSubNum;
							mainPort.SubControlChainList.Add(subControlChain);
							subControlChainIndex++;
						}
					}
					else
					{
						SubControlChain subControlChain = new SubControlChain();
						subControlChain.index = 0;
						subControlChain.DeclareSubControlNum = dMainControl.declareSubNum;
						mainPort.SubControlChainList.Add(subControlChain);
					}

					/****************** 网口主控, 隐藏主控端口和分控链路级 ********************/

					int subControlNum = 0;
					int equControlNum = 0;
					foreach (ControlNode controlNode in controlNodeList)
					{
						// 分控
						if (controlNode.type == 1)
						{
							// 分控 + 分控端口 + 灯具点
							SubControl subControl = new SubControl(controlNode.replyData);
							subControl.index = subControlNum;
							subControl.ProductionInfo.Version = controlNode.version;
							IntPair pair = getDeclarePortAndLampNum(dMainControl, subControl.index);
							if (pair != null)
							{
								subControl.DeclareSubPortNum = pair.val1;
								subControl.DeclareLampNum = pair.val2;
							}

							if (useSwitch == true)
							{
								int macIndex = int.Parse(subMacTable[subControl.index].macIndex);
								mainPort.SubControlChainList[macIndex].SubControlList.Add(subControl);
							}
							else
							{
								mainPort.SubControlChainList[0].SubControlList.Add(subControl);
							}

							subControlNum++;
						}
						// 附属设备
						else if (controlNode.type == 0)
						{
							Equipment equipment = new Equipment(controlNode.replyData);
							equipment.index = equControlNum;
							equipment.ProductionInfo.Version = controlNode.version;

							if (useSwitch == true)
							{
								//int macIndex = int.Parse(subMacTable[equipment.index].macIndex);
								mainPort.SubControlChainList[0].EquControlList.Add(equipment);
							}
							else
							{
								mainPort.SubControlChainList[0].EquControlList.Add(equipment);
							}

							equControlNum++;
						}
					}

					if (subControlNum > 0 || equControlNum > 0)
					{
						for (int k = 0; k < mainPort.SubControlChainList.Count; k++)
						{
							mainPort.SubControlChainList[k].calcSubChainTotalInfo();
						}

						mainPort.calcMainPortTotalInfo();
						mainControl.MainPortList.Add(mainPort);
						mainControl.calcMainPortTotalInfo();
					}

					return mainControl;
				}
				else
				{
					return null;
				}
			}
			else
			{
				return null;
			}
		}

        private MainControl genDetectResultMainControlNet(bool useSwitch, List<ControlNode> controlNodeListNet) {
            MainControl mainControlNet = new MainControl(0);	// 网口主控
            mainControlNet.index = 1;
            MainPort mainPortNet = new MainPort();
            mainPortNet.HideFlag = true;						// 网口主控不显示分端口级

            List<SubControlChain> subControlChainListNet = new List<SubControlChain>();

            List<MacTable> subMacTable = null;
            List<string> macList = null;

            // 不支持交换机
            if (useSwitch == false) {
                SubControlChain subControlChainAllNet = new SubControlChain();
                subControlChainAllNet.HideFlag = true;	// 不显示交换机端口级
                subControlChainListNet.Add(subControlChainAllNet);
            }
                // 支持交换机, 查询分控-MAC映射表
            else {
                subMacTable = baseCoreNet.getLineMacTable("sub");
                macList = baseCoreNet.getMacList();
            }

            int subControlNumNet = 0;
            int equControlNumNet = 0;
            foreach (ControlNode controlNode in controlNodeListNet) {
                // 分控
                if (controlNode.type == 1) {
                    SubControl subControl = new SubControl(controlNode.replyData);
                    subControl.index = controlNode.mySubCtrlDepth + 1;
                    if (controlNode.brotherCount > 0) {
                        subControl.HasErrorNeedDisp = true;
                        subControl.brotherCount = controlNode.brotherCount + 1;
                    }
                    if (controlNode.noContinueFlag == true) {
                        subControl.HasNoContinueMarkNeedDisp = true;
                    }

                    // 不支持交换机
                    if (useSwitch == false) {
                        subControlChainListNet[0].SubControlList.Add(subControl);
                    }
                        // 支持交换机, 将分控按交换机端口 MAC 分组
                    else {
                        SubControlChain parentSubControlChain = null;
                        string macIndex = subMacTable[subControl.index - 1].macIndex;
                        bool addFlag = true;
                        foreach (SubControlChain subControlChain in subControlChainListNet) {
                            if (subControlChain.MacIndex.Equals(macIndex)) {
                                addFlag = false;
                                parentSubControlChain = subControlChain;
                                break;
                            }
                        }

                        if (addFlag == true) {
                            parentSubControlChain = new SubControlChain();
                            parentSubControlChain.index = int.Parse(macIndex) + 1;
                            parentSubControlChain.MacIndex = macIndex;
                            parentSubControlChain.MacValue = macList[int.Parse(macIndex)];
                            subControlChainListNet.Add(parentSubControlChain);
                        }

                        parentSubControlChain.SubControlList.Add(subControl);
                    }

                    subControlNumNet++;
                }
                    // 附属设备
                else if (controlNode.type == 0) {
                    Equipment equipment = new Equipment(controlNode.replyData);
                    equipment.index = controlNode.myEquipmentDepth + 1;
                    if (controlNode.brotherCount > 0) {
                        equipment.HasErrorNeedDisp = true;
                        equipment.brotherCount = controlNode.brotherCount + 1;
                    }
                    if (controlNode.noContinueFlag == true) {
                        equipment.HasNoContinueMarkNeedDisp = true;
                    }

                    // 不支持交换机
                    if (useSwitch == false) {
                        subControlChainListNet[0].EquControlList.Add(equipment);
                    }
                        // 支持交换机, 将分控按交换机端口 MAC 分组
                    else {
                    }

                    equControlNumNet++;
                }
            }

            if (subControlNumNet > 0 || equControlNumNet > 0) {
                for (int k = 0; k < subControlChainListNet.Count; k++) {
                    subControlChainListNet[k].calcSubChainTotalInfo();
                    mainPortNet.SubControlChainList.Add(subControlChainListNet[k]);
                }
                mainPortNet.calcMainPortTotalInfo();
                mainControlNet.MainPortList.Add(mainPortNet);
            } else {
                // 网口通路当前不活跃，置 mainControlNet = null
                mainControlNet = null;
            }

            return mainControlNet;
        }

        private void onUpdateMainTreeUIByArtNet() {
            var useSwitch = baseCoreNet.getUseSwitch();
            var controlNodeListNet = baseCoreNet.getControlNodeList();
            var mainControlNet = genDetectResultMainControlNet(useSwitch, controlNodeListNet);

            if (mainControlNet != null) {
                activePath = ActivePath.Net;
                if (mainSet != null) {
                    mainSet.setActivePath(activePath);
                }
                updateMainTreeUI(mainControlNet, controlNodeListNet);
            }
        }

		#endregion

		#region iBluePlayer消息处理逻辑

		// iBluePlayer 通信测试
		private ShareMessage iBlueTestHandle(ShareMessage iBlueMsg)
		{
			Console.WriteLine(String.Format("iBlue Pipe Test, text=\"{0}\"", iBlueMsg.Parameters[0]));

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 开始下发显示数据
		private ShareMessage startSendDispDataHandle(ShareMessage iblueMsg)
		{
			string x = iblueMsg.Parameters[0];
			string y = iblueMsg.Parameters[1];
			string w = iblueMsg.Parameters[2];
			string h = iblueMsg.Parameters[3];
			string f = iblueMsg.Parameters[4];

			string str = String.Format("Start Send DisplayData, x = {0}, y = {1}, width = {2}, height = {3}, fps = {4}", x, y, w, h, f);
			Console.WriteLine(str);

			int xVal = -1;
			int yVal = -1;
			int wVal = -1;
			int hVal = -1;
			int fVal = -1;
			Int32.TryParse(x, out xVal);
			Int32.TryParse(y, out yVal);
			Int32.TryParse(w, out wVal);
			Int32.TryParse(h, out hVal);
			Int32.TryParse(f, out fVal);

			ShareMessage response = new ShareMessage();

			if (xVal < 0 || yVal < 0 || wVal < 0 || hVal < 0 || fVal < 0)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				// 刚启动时, 收到开始下发显示数据的命令, 暂存
				if (baseCoreNet == null)
				{
					startSendRequestJustStart = true;
					xJustStart = xVal;
					yJustStart = yVal;
					wJustStart = wVal;
					hJustStart = hVal;
					fJustStart = fVal;
				}
				else
				{
					baseCoreNet.changeCaptureSendFPS(fVal);
					baseCoreNet.changeCaptureLocationAndSize(xVal, yVal, wVal, hVal);
					baseCoreNet.startCaptureAndSend();	// 开始下发显示数据
				}
				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 停止下发显示数据
		private ShareMessage stopSendDispDataHandle(ShareMessage iblueMsg)
		{
			Console.WriteLine("Stop Send DisplayData");

			baseCoreNet.stopCaptureAndSend();		// 停止下发显示数据

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 暂停下发显示数据
		private ShareMessage pauseSendDispDataHandle(ShareMessage iblueMsg)
		{
			Console.WriteLine("Pause Send DisplayData");

			baseCoreNet.pauseCaptureAndSend();		// 暂停下发显示数据

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 恢复下发显示数据
		private ShareMessage resumeSendDispDataHandle(ShareMessage iblueMsg)
		{
			Console.WriteLine("Resume Send DisplayData");

			baseCoreNet.resumeCaptureAndSend();		// 恢复下发显示数据

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 改变截屏区域位置
		private ShareMessage changeCaptureAreaHandle(ShareMessage iblueMsg)
		{
			string x = iblueMsg.Parameters[0];
			string y = iblueMsg.Parameters[1];
			string w = iblueMsg.Parameters[2];
			string h = iblueMsg.Parameters[3];

			int xVal = -1;
			int yVal = -1;
			int wVal = -1;
			int hVal = -1;
			Int32.TryParse(x, out xVal);
			Int32.TryParse(y, out yVal);
			Int32.TryParse(w, out wVal);
			Int32.TryParse(h, out hVal);
            

			ShareMessage response = new ShareMessage();

			if (xVal < 0 || yVal < 0 || wVal < 0 || hVal < 0)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				// 刚启动时, 收到更改截屏下发位置的命令, 暂存
				if (baseCoreNet == null)
				{
					changeAreaMsgJustStart = iblueMsg;
					response.Value = "success";
					response.Handled = true;
				}
				else
				{
					bool res = baseCoreNet.changeCaptureLocationAndSize(xVal, yVal, wVal, hVal);
					if (res == true)
					{
						response.Value = "success";
						response.Handled = true;
					}
					else
					{
						response.Value = "wrong parameters";
						response.Handled = false;
					}

					changeAreaMsgJustStart = null;
				}
			}

			return response;
		}

		// 改变截屏帧频
		private ShareMessage changeCaptureFpsHandle(ShareMessage iblueMsg)
		{
			string fps = iblueMsg.Parameters[0];

			int fpsVal = -1;
			Int32.TryParse(fps, out fpsVal);

			ShareMessage response = new ShareMessage();

			if (fpsVal < 0 || fpsVal > 60)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				baseCoreNet.changeCaptureSendFPS(fpsVal);
				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 设置异形映射使能
		private ShareMessage setAddrMapEnableHandle(ShareMessage iblueMsg)
		{
			string enableStr = iblueMsg.Parameters[0];

			ShareMessage response = new ShareMessage();

			enableStr = enableStr.Trim().ToLower();

			if (!enableStr.Equals("true") && !enableStr.Equals("false"))
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				if (enableStr.Equals("true"))
				{
					baseCoreNet.setAddrMapEnable(true);
				}
				else if (enableStr.Equals("false"))
				{
					baseCoreNet.setAddrMapEnable(false);
				}

				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 从 lwf 布线文件中读取 bin 区读取数据 / 从 Json 文件中读取数据
		private ShareMessage readBinDataFromLwfHandle(ShareMessage iblueMsg)
		{
			string infoFilePath = iblueMsg.Parameters[0];
			string srcType = iblueMsg.Parameters[1];

			ShareMessage response = new ShareMessage();
			if (srcType.Equals("lwf"))
			{
				string str = String.Format("Read BinData From Lwf, filePath = {0}", infoFilePath);
				Console.WriteLine(str);

				int readLength = baseCoreNet.readLwfAndBuildMapTable(infoFilePath, false);

				if (readLength != -1)
				{
					response.Value = "success";
					response.Handled = true;
				}
				else
				{
					response.Value = "wrong parameters";
					response.Handled = false;
				}
			}
			else if (srcType.Equals("json"))
			{
				string str = String.Format("Read Data From Json, filePath = {0}", infoFilePath);
				Console.WriteLine(str);

				bool res = baseCoreNet.readJsonAndBuildMapTable(infoFilePath, false);

				if (res == true)
				{
					response.Value = "success";
					response.Handled = true;
				}
				else
				{
					response.Value = "wrong parameters";
					response.Handled = false;
				}
			}
			else
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}

			return response;
		}

		// 查询底层硬件设备的连接状态
		private ShareMessage getSubEquActiveStateHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null && baseCoreNet.getSubEquActiveState() == true)
			{
				response.Parameters = new string[] { "true" };
			}
			else if (baseCoreCom != null && baseCoreCom.getActiveComMainControl() != null)
			{
				response.Parameters = new string[] { "true" };
			}
			else
			{
				response.Parameters = new string[] { "false" };
			}

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 关闭后台 BasePlatformAgent - return null
		private ShareMessage closeAgentHandle(ShareMessage iblueMsg)
		{
			Console.WriteLine("Close BasePlatformAgent by iBluePlayer Command");

			// 设置退出标记
			willCloseByCmd = true;

			return null;
		}

		// 设置是否支持交换机
		private ShareMessage setUseSwitchHandle(ShareMessage iblueMsg)
		{
			string useSwitch = iblueMsg.Parameters[0];

			ShareMessage response = new ShareMessage();
			useSwitch = useSwitch.Trim().ToLower();
			if (!useSwitch.Equals("true") && !useSwitch.Equals("false"))
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				if (useSwitch.Equals("true"))
				{
					baseCoreNet.setUseSwitch(true);
				}
				else if (useSwitch.Equals("false"))
				{
					baseCoreNet.setUseSwitch(false);
				}

				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 读取多路交换机配置文件
		private ShareMessage readSwitchConfigFileHandle(ShareMessage iblueMsg)
		{
			string configFilePath = iblueMsg.Parameters[0];

			ShareMessage response = new ShareMessage();

			string readRes = baseCoreNet.readSwitchConfigFileJson(configFilePath);

			if (readRes.Equals("success"))
			{
				response.Value = "success";
				response.Handled = true;
			}
			else
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}

			return response;
		}

		// 显示系统界面
		private ShareMessage showHardConfigFormHandle(ShareMessage iblueMsg)
		{
			Console.WriteLine("\n--------------- Show HardConfig Form ---------------");

			ShareMessage response = new ShareMessage();

            if (baseCoreNet == null && baseCoreCom == null)
            {
                response.Value = "isIniting";
            }
            else
			{
				if (hardConfigFormHasShown == false)
				{
					hardConfigFormHasShown = true;
					Thread t = new Thread(() =>
					{
						if (mainSet == null)
						{
							mainSet = new Form_MainSet();
							mainSet.setBaseCoreNet(this.baseCoreNet, this.baseCoreCom);
							mainSet.setIBluePlayerPlayingState(iBluePlayerIsPlaying);
							mainSet.setShowTestTabEnable(showTestTabEnable);
                            mainSet.setShowMainTabEnable(showMainTabEnable);
						}
						else
						{
							mainSet.collapseConfigPanel();
						}

						// to fix 2017.12.13
						if (baseCoreNet != null)
						{
							baseCoreNet.WriteSubStateUpdated += mainSet.updateApplyOrTestSubSendProcess;
						}

						Process[] processes = Process.GetProcessesByName("BasePlatformAgent");
						if (processes.Length > 0)
						{
							IntPtr hwnd = processes[0].MainWindowHandle;
							mainSet.ShowDialog(new WindowWrapper(hwnd));
						}
						else
						{
							mainSet.ShowDialog();
						}

						if (baseCoreNet != null)
						{
							baseCoreNet.WriteSubStateUpdated -= mainSet.updateApplyOrTestSubSendProcess;
						}

						hardConfigFormHasShown = false;
					});
					t.SetApartmentState(ApartmentState.STA);
					t.IsBackground = true;
					t.Start();
				}
				else
				{
					Console.WriteLine("HardConfig Form has Already been Shown");
					mainSet.TopMost = true;
					mainSet.TopMost = false;
				}

				response.Value = "success";
			}
			
			response.Handled = true;

			return response;
		}

		// 查询异形映射参数
		private ShareMessage getAddrMapParameterHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				string s1 = getConfigValue(agentIni, "addrMapEnable");
				string s2 = getConfigValue(agentIni, "addrMapFileType");
				string s3 = getConfigValue(agentIni, "addrMapFilePath");
				string s4 = baseCoreNet.getBaseMapMode().ToString();
				string s5 = baseCoreNet.getBaseColorString();
				string s6 = baseCoreNet.getBaseMapSrcType().ToString();

				response.Parameters = new string[] { s1, s2, s3, s4, s5, s6 };
			}
			else
			{
				response.Parameters = new string[] { "false", "", "", "0", "0", "0" };
			}

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 查询异形映射表
		private ShareMessage getAddrMapTableHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				string type = iblueMsg.Parameters[0];
				if (type.Equals("addrMap") && baseCoreNet.getAddrMap() != null)
				{
					response.PayloadData = new int[baseCoreNet.getAddrMap().Length];
					Array.Copy(baseCoreNet.getAddrMap(), response.PayloadData, response.PayloadData.Length);
				}
				else if (type.Equals("addrMapType") && baseCoreNet.getAddrMapType() != null)
				{
					response.PayloadData = new int[baseCoreNet.getAddrMapType().Length];
					Array.Copy(baseCoreNet.getAddrMapType(), response.PayloadData, response.PayloadData.Length);
				}
				else if (type.Equals("addrMapOffset") && baseCoreNet.getAddrMapOffset() != null)
				{
					response.PayloadData = new int[baseCoreNet.getAddrMapOffset().Length];
					Array.Copy(baseCoreNet.getAddrMapOffset(), response.PayloadData, response.PayloadData.Length);
				}

				response.Value = "success";
			}
			else
			{
				response.Parameters = new string[] { "false", "", "", "0", "0", "0" };
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 查询内核版本
		private ShareMessage getAgentVersionHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
                var version = getVersion();
				response.Parameters = new string[] { version, baseCoreNet.getVersion() };
				response.Value = "success";
			}
			else
			{
				response.Parameters = new string[] { "", "" };
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 根据 subIndex 查询声明的分控端口数和灯具数
		private IntPair getDeclarePortAndLampNum(DMainControl dMainControl, int subIndex)
		{
			if (dMainControl == null || dMainControl.declareSubControlList == null)
			{
				return null;
			}

			if (dMainControl.declareSubControlList.Count == 0)
			{
				return null;
			}

			foreach (DSubControl subControl in dMainControl.declareSubControlList)
			{
				if (subControl.subControlIndex == subIndex)
				{
					return new IntPair(subControl.declarePortNum, subControl.declareLampNum);
				}
			}

			return null;
		}

		// 查询底层设备链信息（Json格式）
		private ShareMessage getDeviceChainJsonHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				MainControl mainControl = getDetectResultMainControl();

				if (mainControl == null)
				{
					response.PayloadStr = "";
				}
				else
				{
					string jsonStr = JsonConvert.SerializeObject(mainControl);
					response.PayloadStr = jsonStr;
				}

				response.Value = "success";
			}
			else
			{
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 查询底层设备链摘要信息（Json格式）
		private ShareMessage getDeviceChainStatusJsonHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				MainControl mainControl = getDetectResultMainControl();

				if (mainControl == null)
				{
					response.PayloadStr = "";
				}
				else
				{
					ChainStatus chainStatus = new ChainStatus();

					int DeclareSubControlNum = 0;
					int TotalSubControlNum = 0;
					int ErrorSubControlNum = 0;
					int TotalLampNum = 0;
					int ErrorLampNum = 0;

                    chainStatus.FaultDetails = new List<SubFaultDetail>();

					bool hasNoDeclareSubControlNum = false;
					foreach (MainPort mainPort in mainControl.MainPortList)
					{
						foreach (SubControlChain subControlChain in mainPort.SubControlChainList)
						{
							if (subControlChain.DeclareSubControlNum < 0)
							{
								hasNoDeclareSubControlNum = true;
							}

							DeclareSubControlNum += subControlChain.DeclareSubControlNum;
							TotalSubControlNum += subControlChain.TotalSubControlNum;
							ErrorSubControlNum += subControlChain.ErrorSubControlNum;
							TotalLampNum += subControlChain.TotalLampNum;
							ErrorLampNum += subControlChain.ErrorLampNum;

                            foreach (var subControl in subControlChain.SubControlList)
                            {
                                if (subControl.FaultDetail != null)
                                {
                                    chainStatus.FaultDetails.Add(subControl.FaultDetail.Clone());
                                }
                            }
						}
					}

					// 分控总数
					if (hasNoDeclareSubControlNum == true)
					{
						chainStatus.SubTotalNum = TotalSubControlNum;
					}
					else
					{
						chainStatus.SubTotalNum = DeclareSubControlNum;
					}
					// 分控联机数
                    chainStatus.SubConnectNum = TotalSubControlNum;
                    // 分控故障数
                    chainStatus.SubErrorNum = ErrorSubControlNum;
					// 灯总数
					chainStatus.LampTotalNum = TotalLampNum;
					// 灯故障数
					chainStatus.LampErrorNum = ErrorLampNum;
					// 故障类型
					StringBuilder errorStringBuilder = new StringBuilder();
					if (chainStatus.SubConnectNum < chainStatus.SubTotalNum)
					{
						errorStringBuilder.Append("1,");
					}
					if (chainStatus.LampErrorNum > 0)
					{
						errorStringBuilder.Append("2,");
					}
					// 通信不良/通信异常
					string s = errorStringBuilder.ToString();
					if (s.Equals(""))
					{
						s = "0";
					}
					else
					{
						s = s.Substring(0, s.Length - 1);
					}
					chainStatus.ErrorType = s;
					// 故障时间
					chainStatus.ErrorTime = DateTime.Now.ToString();

					//string jsonStr = JsonConvert.SerializeObject(chainStatus);
                    var jsonStr = chainStatus.ToString();

					response.PayloadStr = jsonStr;
				}

				response.Value = "success";
			}
            else if (baseCoreCom != null)
            {
                ChainStatus chainStatus = new ChainStatus();

                chainStatus.MainControlStatus = baseCoreCom.getActiveComMainControlDviStatus().ToString();
                chainStatus.MainControlConnected = baseCoreCom.getMainControlNum().ToString();

                // 主控连接状态返回值由界面指定：0-未连接, 1~3-已连接1~3个主控
                if (mainSet != null && mainSet.getMainControlConnected() < 4)
                {
                    chainStatus.MainControlConnected = mainSet.getMainControlConnected().ToString();
                }

                // 主控 DVI 状态返回值由界面指定：0-不支持, 1-正常, 2-错误
                if (mainSet != null && mainSet.getMainControlDviMode() < 3)
                {
                    chainStatus.MainControlStatus = mainSet.getMainControlDviMode().ToString();
                }

                //string jsonStr = JsonConvert.SerializeObject(chainStatus);
                var jsonStr = chainStatus.ToString();

                response.PayloadStr = jsonStr;

                response.Value = "success";
            }
            else
            {
                response.Value = "error";
            }

			response.Handled = true;

			return response;
		}

		// 查询底层设备链详细信息（Json格式）
		private ShareMessage getDeviceChainDetailJsonHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				MainControl mainControl = getDetectResultMainControl();

				if (mainControl == null)
				{
					response.PayloadStr = "";
				}
				else
				{
					string jsonStr = JsonConvert.SerializeObject(mainControl.MainPortList[0].SubControlChainList);
					response.PayloadStr = jsonStr;
				}

				response.Value = "success";
			}
			else
			{
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 设置 iBluePlayer 的播放状态：true/false
		private ShareMessage setPlayingStateHandle(ShareMessage iblueMsg)
		{
			string playing = iblueMsg.Parameters[0];

			ShareMessage response = new ShareMessage();
			playing = playing.Trim().ToLower();
			if (!playing.Equals("true") && !playing.Equals("false"))
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				//Console.WriteLine("Set iBluePlayer Playing State = " + playing);

				if (playing.Equals("true"))
				{
					iBluePlayerIsPlaying = true;
				}
				else if (playing.Equals("false"))
				{
					iBluePlayerIsPlaying = false;
				}

				if (mainSet != null)
				{
					mainSet.setIBluePlayerPlayingState(iBluePlayerIsPlaying);
				}

				if (playing.Equals("true") && mainSet != null && mainSet.Visible)
				{
					// iBluePlayer有内容在播放，关闭硬件设置界面
					mainSet.BeginInvoke(mainSet.collapseConfigPanelDelegate);
				}

				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 查询底层硬件配置窗展开状态
		private ShareMessage getConfigExpandStateHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (mainSet == null || mainSet.Visible == false)
			{
				response.Parameters = new string[] { "false" };
				response.Value = "success";
			}
			else if (mainSet.Visible == true)
			{
				response.Parameters = new string[] { mainSet.getConfigPanelExpanded().ToString() };
				response.Value = "success";
			}
			else
			{
				response.Parameters = new string[] { "", "" };
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 设置节目亮度
		private ShareMessage setProgramBrightnessHandle(ShareMessage iblueMsg)
		{
			string brightStr = iblueMsg.Parameters[0];

			int brightVal = -1;
			Int32.TryParse(brightStr, out brightVal);

			ShareMessage response = new ShareMessage();

			if (brightVal < 0 || brightVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				if (baseCoreNet != null)
				{
					baseCoreNet.setProgramBrightness(brightVal);
				}
				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 查询分控配置 sub 数据
		private ShareMessage getSubConfigDataHandle(ShareMessage iblueMsg)
		{
			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				byte[] returnBytes = new byte[128 * 1024];
				if (mainSet == null)
				{
					string defaultL9FilePath = getAppPath() + @"\conf\defaultL9.sub";
					if (File.Exists(defaultL9FilePath))
					{
						FileStream fs = new FileStream(defaultL9FilePath, FileMode.Open);
						if (fs.Length == 128 * 1024)
						{
							BinaryReader reader = new BinaryReader(fs);
							returnBytes = reader.ReadBytes(128 * 1024);
							response.PayloadStr = "default.sub";
						}
					}
				}
				else
				{
					returnBytes = mainSet.getSubConfigData();
					response.PayloadStr = mainSet.getSubConfigFilePath();
				}
				
				response.PayloadBytes = new byte[128 * 1024];
				Array.Copy(returnBytes, response.PayloadBytes, 128 * 1024);

				response.Value = "success";
			}
			else
			{
				response.Value = "error";
			}

			response.Handled = true;

			return response;
		}

		// 设置 MCU 显示参数
		private ShareMessage setMcuDispParameterHandle(ShareMessage iblueMsg)
		{
			string brightTotal = iblueMsg.Parameters[0];
			string brightR = iblueMsg.Parameters[1];
			string brightG = iblueMsg.Parameters[2];
			string brightB = iblueMsg.Parameters[3];
			string brightW = iblueMsg.Parameters[4];
			string gamma = iblueMsg.Parameters[5];

			ShareMessage response = new ShareMessage();

			int brightTotalVal = -1;
			bool parseRes0 = Int32.TryParse(brightTotal, out brightTotalVal);
			int brightRVal = -1;
			bool parseRes1 = Int32.TryParse(brightR, out brightRVal);
			int brightGVal = -1;
			bool parseRes2 = Int32.TryParse(brightG, out brightGVal);
			int brightBVal = -1;
			bool parseRes3 = Int32.TryParse(brightB, out brightBVal);
			int brightWVal = -1;
			bool parseRes4 = Int32.TryParse(brightW, out brightWVal);
			int gammaVal = -1;
			bool parseRes5 = Int32.TryParse(gamma, out gammaVal);

			if (parseRes0 == false || brightTotalVal < 0 || brightTotalVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else if (parseRes1 == false || brightRVal < 0 || brightRVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else if (parseRes2 == false || brightGVal < 0 || brightGVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else if (parseRes3 == false || brightBVal < 0 || brightBVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else if (parseRes4 == false || brightWVal < 0 || brightWVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else if (parseRes5 == false || gammaVal < 0 || gammaVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else {
                int[] paras = new int[] { brightTotalVal, brightRVal, brightGVal, brightBVal, brightWVal, gammaVal };
                if (baseCoreNet != null) {
                    // 解析参数，整体亮度和 Gamma 值暂时未填写，RGBW 分色亮度有效
                    baseCoreNet.setMcuDispParameter(paras);
                }
                if (baseCoreCom != null) {
                    // 解析参数，整体亮度和 Gamma 值暂时未填写，RGBW 分色亮度有效
                    baseCoreCom.setMcuDispParameter(paras);
                }
				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 设置用户颜色模式
		private ShareMessage setUserColorTypeHandle(ShareMessage iblueMsg)
		{
			string userColorTypeStr = iblueMsg.Parameters[0];

			int userColorTypeVal = -1;
			Int32.TryParse(userColorTypeStr, out userColorTypeVal);

			ShareMessage response = new ShareMessage();

			if (userColorTypeVal < 0 || userColorTypeVal > 255)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				if (baseCoreNet != null)
				{
					baseCoreNet.setUserColorType(userColorTypeVal);

                    if (userColorTypeVal == 254)
                    {
                        string WhiteChannelStr = iblueMsg.Parameters[1];
                        int WhiteChannelVal = 0;
                        int.TryParse(WhiteChannelStr, out WhiteChannelVal);
                        baseCoreNet.setUserChannelLvl(WhiteChannelVal);
                    }
				}
				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

		// 设置 DatPlayForm 播放掩码
		private ShareMessage setAddrMapDatPlayingMaskHandle(ShareMessage iblueMsg)
		{
			string maskValueStr = iblueMsg.Parameters[0].ToLower();
			bool maskValue = (maskValueStr.Equals("true") ? true : false);

			ShareMessage response = new ShareMessage();

			if (baseCoreNet != null)
			{
				baseCoreNet.setAddrMapDatPlayingMask(maskValue);
			}
			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// 设置用户语言
		private ShareMessage setUserLanguageHandle(ShareMessage iblueMsg)
		{
			string userLanguageStr = iblueMsg.Parameters[0];

			int userLanguageVal = -1;
			Int32.TryParse(userLanguageStr, out userLanguageVal);

			ShareMessage response = new ShareMessage();

			if (userLanguageVal < 0 || userLanguageVal > 2)
			{
				response.Value = "wrong parameters";
				response.Handled = false;
			}
			else
			{
				if (userLanguageVal == 0)		// 简体中文
				{
					LanguageOper.LocalLanguage = LanguageEnum.CHS;
				}
                else if (userLanguageVal == 1)	// 英文
				{
					LanguageOper.LocalLanguage = LanguageEnum.EN;
				}
                else if (userLanguageVal == 2)	// 繁体中文
				{
					LanguageOper.LocalLanguage = LanguageEnum.CHT;
				}

                if (userLanguageVal == 2) // 暂不支持繁体中文
                {
                    LanguageOper.LocalLanguage = LanguageEnum.CHS;
                }

                //mainSet.setShowTestTabEnable(true);
                
				mainSet.setLanguageText();
				mainSet.setSubFormText();

                //mainSet.setShowTestTabEnable(false);

				response.Value = "success";
				response.Handled = true;
			}

			return response;
		}

        // 发起ArtNet设备链查询
        private ShareMessage startQueryArtDeviceChainHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                response.Value = "success";
                var t = new Thread(() => {
                    if (!isQueryArtDevChainDone) {
                        return;
                    }
                    isQueryArtDevChainDone = false;
                    if (!rdmTestEnable) {
                        baseCoreNet.RestartQueryUnvUidList();
                        baseCoreNet.SetRequeryState(false);
                        baseCoreNet.ReadArtDeviceChainDetail(); 
                    }
                    isQueryArtDevChainDone = true;
                });
                t.IsBackground = true;
                t.Start();
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

        // 获取ArtNet基准设备链信息
        private ShareMessage getBaseArtDeviceChainHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                if (!isBaseArtDevChainExist) {
                    response.Value = "base chain not exist";
                } else {
                    var json = baseArtDevChain.ToString();
                    response.PayloadStr = json;
                    response.Value = "success";
                }
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

        // 获取ArtNet当前设备链信息
        private ShareMessage getCurrentArtDeviceChainHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                if (!isQueryArtDevChainDone) {
                    response.Value = "Is Querying";
                } else {
                    var devChainList = baseCoreNet.ArtDevDetailList;
                    if (rdmTestEnable) {
                        devChainList = getTestArtDevChain();
                    }
                    var json = devChainList.ToString(); 
                    response.PayloadStr = json;
                    response.Value = "success";
                }
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

        // 设置ArtNet当前设备链信息设为基准
        private ShareMessage setCurrentArtDeviceChainToBaseHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                if (!isQueryArtDevChainDone) {
                    response.Value = "Is Querying";
                } else {
                    var devChainList = baseCoreNet.ArtDevDetailList;
                    if (rdmTestEnable) {
                        devChainList = getTestArtDevChain();
                    }
                    baseArtDevChain = devChainList.Clone();
                    saveArtDeviceChainIni();
                    isBaseArtDevChainExist = true;
                    response.Value = "success";
                }
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

        // 获取ArtNet错误信息
        private ShareMessage getErrorArtDeviceHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                if (!isBaseArtDevChainExist) {
                    response.Value = "base chain not exist";
                } else {
                    if (!rdmTestEnable) {
                        if (!baseCoreNet.HasRequeryInfo()) { //没有检测信息
                            response.Value = "querying";
                        } else {
                            if (baseCoreNet.GetRequeryState()) { //当前检测信息已经被获取过
                                response.Value = "told";
                            } else {
                                var faultList = baseCoreNet.CompareWithBaseArtDevChain(baseArtDevChain);
                                if (faultList == null) {
                                    response.Value = "base chain not exist";
                                } else {
                                    response.PayloadStr = faultList.ToString();
                                    typeLog(response.PayloadStr, LogFile.Debug);
                                    response.Value = "success";
                                    baseCoreNet.SetRequeryState(true);
                                }
                            }
                        }
                    } else {
                        var faultList = getTestArtDevFault();
                        response.PayloadStr = faultList.ToString();
                        response.Value = "success";
                    }
                }
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

        // 获取ArtNet灯具详情
        private ShareMessage getArtDeviceDetailHandle(ShareMessage iblueMsg) {
#if !ARTNET_SUPPORTED
            return genUnsupportedMessage();
#else
            var uid = iblueMsg.Parameters[0];
            var response = new ShareMessage();

            if (baseCoreNet != null) {
                if (!rdmTestEnable) {
                    var unv = baseCoreNet.GetSpecificUnv(uid);
                    if (unv == -1) {
                        response.Value = "error";
                    } else {
                        var succ = false;
                        var info = baseCoreNet.ReadArtDevDetail(uid, unv, true);
                        if (info == null) {
                            succ = false;
                        } else {
                            succ = true;
                            response.PayloadStr = info.ToString();
                        }
                        response.Value = succ ? "success" : "error";
                    }
                } else {
                    var info = getTestArtDevInfo(uid);
                    response.PayloadStr = info.ToString();
                    response.Value = "success";
                }
            } else {
                response.Value = "error";
            }

            response.Handled = true;

            return response;
#endif
        }

		#endregion

		#region ledDebug消息处理逻辑

		// LedDebug 通信测试
		private ShareMessage ledDebugTestHandle(ShareMessage ledMsg)
		{
			string text = ledMsg.Parameters[0];

			string str = String.Format("LedDebug Pipe Test, text=\"{0}\"", text);
			Console.WriteLine(str);

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		// LedDebug 查询分控数量
		private ShareMessage ledDebugGetSubControlNumHandle(ShareMessage ledMsg)
		{
			Console.WriteLine("LedDebug GetSubControlNum");

			ShareMessage response = new ShareMessage();

			int subNum = 0;
			if (baseCoreNet != null)
			{
				subNum = baseCoreNet.getSubCount();
			}

			response.Value = "success";
			response.Handled = true;
			response.Parameters = new string[] { subNum.ToString() };

			return response;
		}

		// LedDebug 设置/取消设置有效的分控号、端口号
		private ShareMessage ledDebugSetEffectSubAndPortHandle(ShareMessage ledMsg)
		{
			string[] parameters = ledMsg.Parameters;

			StringBuilder sb = new StringBuilder();
			foreach (string s in parameters)
			{
				sb.Append("," + s);
			}
			string statusStr = sb.ToString();
			if (statusStr.Length > 0)
			{
				statusStr = statusStr.Substring(1);
			}
			
			//Console.WriteLine("LedDebug SetEffectSubAndPort, statusStr = " + statusStr);

			try
			{
				if (baseCoreNet != null)
				{
					baseCoreNet.ledDebugSetEffectSubAndPort(statusStr);
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
			}

			ShareMessage response = new ShareMessage();

			response.Value = "success";
			response.Handled = true;

			return response;
		}

		#endregion

		#region 系统配置辅助函数

		// 获得应用程序 exe 所在路径
		private string getAppPath()
		{
			return (new FileInfo(Application.ExecutablePath)).Directory.ToString();
		}

        // 获取版本号
        private string getVersion() {
            var date = System.IO.File.GetLastWriteTime(this.GetType().Assembly.Location);
            var version = string.Format("BasePlatformAgent: v{0} @ {1}.{2}.{3}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(), date.Year, date.Month, date.Day);
            return version;
        }

		// 从配置文件 configFilePath 中读取 key 的值 value, 若无此配置或者读取错误, 返回空串 ""
		private string getConfigValue(string configFilePath, string key)
		{
			StreamReader sr = null;
			try
			{
				if (!File.Exists(configFilePath) && File.Exists(configFilePath + ".tmp"))
				{
					File.Move(configFilePath + ".tmp", configFilePath);
				}

				if (File.Exists(configFilePath))
				{
					sr = new StreamReader(new FileStream(configFilePath, FileMode.Open));
					string returnValue = "";
					while (true)
					{
						string line = sr.ReadLine();
						if (line == null)
						{
							break;
						}
						else if (line.Trim().ToLower().StartsWith(key.ToLower()))
						{
							string[] subStr = line.Split('=');
							if (subStr.Length >= 2)
							{
								returnValue = subStr[1];
							}
						}
					}
					return returnValue;
				}
				else
				{
					string msg = string.Format("无法找到配置文件 {0}", configFilePath);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.4"), configFilePath);
					}
					MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return "";
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return "";
			}
			finally
			{
				if (sr != null)
				{
					sr.Close();
				}
			}
		}

		// 向配置文件 configFilePath 中写入 key 的值 value, 若成功返回true, 失败返回false
		private bool setConfigValue(string configFilePath, string key, string value)
		{
			StreamReader sr = null;
			StreamWriter sw = null;
			try
			{
				if (File.Exists(configFilePath))
				{
					sr = new StreamReader(new FileStream(configFilePath, FileMode.Open));
					sw = new StreamWriter(new FileStream(configFilePath + ".tmp", FileMode.Create));

					while (true)
					{
						string line = sr.ReadLine();
						if (line == null)
						{
							break;
						}
						else if (line.Trim().ToLower().StartsWith(key.ToLower()))
						{
							string[] subStr = line.Split('=');
							line = subStr[0] + "=" + value;
							sw.WriteLine(line);
						}
						else
						{
							sw.WriteLine(line);
						}
					}

					sr.Close();
					sw.Flush();
					sw.Close();
					sw = null;

					try
					{
						File.Delete(configFilePath);
						File.Move(configFilePath + ".tmp", configFilePath);
					}
					catch (Exception)
					{
						;
					}

					return true;
				}
				else
				{
					string msg = string.Format("无法找到配置文件 {0}", configFilePath);
					if (LanguageOper.available == true)
					{
						msg = string.Format(LanguageOper.ReadValue(section, "msgStr.4"), configFilePath);
					}
					MessageBox.Show(msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
					return false;
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.Message + ex.StackTrace);
				return false;
			}
		}

		// 从 defaultL9.sub 文件中读取异形映射模式和颜色排列字符串
		private void readMapModeAndColorStringFromSub(string subFilePath)
		{
			if (File.Exists(subFilePath))
			{
				RVCardL9Config rvCardL9Config = new RVCardL9Config();
				rvCardL9Config.LoadFromSub(subFilePath);

				// 规则排列
				if (rvCardL9Config.colorOrderMode == 0)
				{
					// 三色模式
					baseCoreNet.setBaseMapMode(MapMode.Baned);
					
					StringBuilder sb = new StringBuilder();
					byte[] manualColorArray = rvCardL9Config.GetManualColorArray();
					sb.Append(getColorChar(manualColorArray[1]));
					sb.Append(getColorChar(manualColorArray[3]));
					sb.Append(getColorChar(manualColorArray[5]));
					baseCoreNet.setBaseColorString(sb.ToString());
				}
				// 任意排列
				else
				{
					// 三色模式
					if (rvCardL9Config.mainColorMode == 3)
					{
						baseCoreNet.setBaseMapMode(MapMode.Baned);

						StringBuilder sb = new StringBuilder();
						byte[] manualColorArray = rvCardL9Config.GetManualColorArray();
						sb.Append(getColorChar(manualColorArray[1]));
						sb.Append(getColorChar(manualColorArray[3]));
						sb.Append(getColorChar(manualColorArray[5]));
						baseCoreNet.setBaseColorString(sb.ToString());
					}
					// 四色模式
					else if (rvCardL9Config.mainColorMode == 4)
					{
						// 四色纯模式
						if (rvCardL9Config.fourColorMode == 1)
						{
							baseCoreNet.setBaseMapMode(MapMode.FourPure);
						}
						// 四色增强模式
						else if (rvCardL9Config.fourColorMode == 2)
						{
							baseCoreNet.setBaseMapMode(MapMode.FourIncrease);
						}

						StringBuilder sb = new StringBuilder();
						byte[] manualColorArray = rvCardL9Config.GetManualColorArray();
						sb.Append(getColorChar(manualColorArray[1]));
						sb.Append(getColorChar(manualColorArray[3]));
						sb.Append(getColorChar(manualColorArray[5]));
						sb.Append(getColorChar(manualColorArray[7]));
						baseCoreNet.setBaseColorString(sb.ToString());
					}
				}
			}
		}
        // 保存低灰过滤数据
        private void SaveLowestGrayData()
        {
            setConfigValue(agentIni, "lowestGray", baseCoreNet.getLowestGray().ToString());
        }

		// 辅助函数：根据索引获取颜色描述
		private char getColorChar(byte colorIndex)
		{
			switch (colorIndex)
			{
				case 0:
					return 'R';
				case 1:
					return 'G';
				case 2:
					return 'B';
				case 3:
					return 'N';
				case 4:
					return 'W';
				case 5:
					return 'Y';
				default:
					return 'N';
			}
		}

        private void readArtDeviceChainIni() {
            if (!File.Exists(artDevChainIni)) {
                return;
            }
            baseArtDevChain = ArtDeviceChain.LoadFromFile(artDevChainIni);
            if (baseArtDevChain != null) {
                isBaseArtDevChainExist = true;
                if (baseCoreNet != null) {
                    baseCoreNet.SetBaseArtDevChain(baseArtDevChain);
                }
            }
        }

        private void saveArtDeviceChainIni() {
            baseArtDevChain.SaveToFile(artDevChainIni); 
            if (baseCoreNet != null) {
                baseCoreNet.SetBaseArtDevChain(baseArtDevChain);
            }
        }

		#endregion

		#region 日志操作

		// 打印日志
		public void typeLog(Object obj, LogFile logFile = LogFile.Normal, LogTarget logTarget = LogTarget.Both)
		{
			if (typeLogEnable == false)
			{
				return;
			}

			string str = obj.ToString();

			if (logTarget == LogTarget.CmdOnly)
			{
				Console.WriteLine(str);
			}
			else
			{
				if (logTarget == LogTarget.Both)
				{
					Console.WriteLine(str);
				}

				if (logFile == LogFile.Normal && normalLogEnable == true)
				{
					Log.NormalLogger.Info(str);
				}
				else if (logFile == LogFile.Test && testLogEnable == true)
				{
					Log.TestLogger.Info(str);
				}
				else if (logFile == LogFile.DetectNet && detectNetLogEnable == true)
				{
					Log.DetectNetLogger.Info(str);
				}
				else if (logFile == LogFile.Debug && debugLogEnable == true)
				{
					Log.DebugLogger.Info(str);
				}
			}
		}

		#endregion

        #region TEST
        private static readonly string testUID = "02f000010203";
        private ArtDeviceInfo getTestArtDevInfo(string uid) {
            var devInfo = new ArtDeviceInfo();
            devInfo.UID = uid;
            devInfo.Version = "1";
            devInfo.ModelID = "0100";
            devInfo.Category = "0100";
            devInfo.SoftwareVersionID = "1";
            devInfo.DMXAddr = 1;
            devInfo.SubDeviceCount = 1;
            devInfo.SensorCount = 1;
            devInfo.DeviceLabel = "aaa";
            devInfo.ManufactorLabel = "iColor";
            devInfo.SoftwareVersionLabel = "bbb";
            var sensorInfo = new ArtSensorInfo();
            var sensorDef = new ArtSensorDef();
            sensorDef.ID = 1;
            sensorDef.Type = SensorType.Temperature;
            sensorDef.Unit = SensorUnit.Centigrade;
            sensorDef.Prefix = 1;
            sensorDef.RangeMin = 0;
            sensorDef.RangeMax = 500;
            sensorDef.NormalMax = 200;
            sensorDef.NormalMin = 0;
            sensorDef.Description = "Temperature";
            var sensorVal = new ArtSensorValue();
            sensorVal.ID = 1;
            sensorVal.CurrVal = 33;
            sensorVal.LowestVal = 0;
            sensorVal.HighestVal = 0;
            sensorVal.RecordVal = 0;
            sensorVal.Prefix = 1;

            sensorInfo.Definition = sensorDef;
            sensorInfo.Value = sensorVal;
            devInfo.SensorList = new List<ArtSensorInfo> { sensorInfo };
            return devInfo;
        }

        private ArtDeviceChain getTestArtDevChain() {
            var chain = new ArtDeviceChain();
            var list = new List<ArtPortDetail>();
            var devInfo = getTestArtDevInfo(testUID);
            for (var i = 0; i < 8; i++) {
                var detail = new ArtPortDetail();
                detail.SubID = 1;
                detail.PortID = i + 1;
                detail.Universe = i + 1;
                if (i == 0) {
                    detail.DeviceList = new List<ArtDeviceInfo> { devInfo };
                }
                list.Add(detail);
            }
            chain.DetailList[1] = list;
            return chain;
        }

        private ArtFaultTotal getTestArtDevFault() {
            var faultList = new ArtFaultTotal();
            var devFault = new ArtDeviceFault();
            devFault.SubID = 1;
            devFault.PortID = 1;
            devFault.UID = testUID;
            devFault.FaultType = ArtFaultType.Undetect;
            devFault.FaultTime = DateTime.Now;
            faultList.Details = new List<ArtDeviceFault> { devFault };
            return faultList;
        }

        private ShareMessage genUnsupportedMessage() {
            var response = new ShareMessage();
            response.Value = "Unsupported";
            response.Handled = true;
            return response;
        }
        #endregion
    }

	public class WindowWrapper : System.Windows.Forms.IWin32Window
	{
		private IntPtr _hwnd;

		public WindowWrapper(IntPtr handle)
		{
			_hwnd = handle;
		}

		public IntPtr Handle
		{
			get
			{
				return _hwnd;
			}
		}
	}

	internal class IntPair
	{
		public int val1 = 0;

		public int val2 = 0;

		public IntPair(int v1, int v2)
		{
			val1 = v1;
			val2 = v2;
		}
	}
}
